From b757e1fccb31add36ca4718c8f9f332e6cd0a822 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 31 Jan 2022 21:51:23 +0800 Subject: [PATCH] 多模块重构 7:pay 模块的初始化 --- pom.xml | 1 + yudao-admin-server/pom.xml | 57 ++++++--------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/PayAppController.java | 163 ------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppBaseVO.java | 37 ------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppCreateReqVO.java | 14 -------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExcelVO.java | 41 ----------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExportReqVO.java | 41 ----------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageItemRespVO.java | 50 -------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageReqVO.java | 43 ------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppRespVO.java | 19 ------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateReqVO.java | 18 ------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateStatusReqVO.java | 21 --------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/PayChannelController.java | 129 --------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelBaseVO.java | 39 --------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelCreateReqVO.java | 21 --------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExcelVO.java | 50 -------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExportReqVO.java | 44 -------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelPageReqVO.java | 46 ---------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelRespVO.java | 21 --------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelUpdateReqVO.java | 21 --------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java | 116 -------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java | 30 ------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java | 14 -------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java | 40 ---------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java | 38 -------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java | 40 ---------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java | 30 ------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java | 18 ------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java | 21 --------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayOrderController.java | 177 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayRefundController.java | 174 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderBaseVO.java | 108 ------------------------------------------------------------------------------------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderDetailsRespVO.java | 53 ----------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExcelVO.java | 91 ------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExportReqVO.java | 112 ---------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageItemRespVO.java | 41 ----------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageReqVO.java | 118 ---------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderRespVO.java | 28 ---------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundBaseVO.java | 110 -------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundCreateReqVO.java | 12 ------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundDetailsRespVO.java | 44 -------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExcelVO.java | 88 ---------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExportReqVO.java | 111 --------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageItemRespVO.java | 36 ------------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageReqVO.java | 116 -------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundRespVO.java | 23 ----------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundUpdateReqVO.java | 17 ----------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/app/PayAppConvert.java | 39 --------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/channel/PayChannelConvert.java | 42 ------------------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java | 34 ---------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/order/PayOrderConvert.java | 104 -------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/package-info.java | 6 ------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/refund/PayRefundConvert.java | 90 ------------------------------------------------------------------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md | 1 - yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/app/PayAppMapper.java | 83 ----------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/channel/PayChannelMapper.java | 91 ------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java | 53 ----------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderExtensionMapper.java | 16 ---------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderMapper.java | 79 ------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayRefundMapper.java | 61 ------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java | 1 - yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/notify/PayNotifyJob.java | 29 ----------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/package-info.java | 1 - yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/package-info.java | 7 ------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppService.java | 103 ------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/impl/PayAppServiceImpl.java | 189 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelService.java | 107 ----------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java | 161 ----------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java | 104 -------------------------------------------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java | 150 ------------------------------------------------------------------------------------------------------------------------------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderExtensionService.java | 48 ------------------------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderService.java | 67 ------------------------------------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayRefundService.java | 41 ----------------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderExtensionServiceImpl.java | 35 ----------------------------------- yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderServiceImpl.java | 54 ------------------------------------------------------ yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayRefundServiceImpl.java | 42 ------------------------------------------ yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbAndRedisUnitTest.java | 48 ------------------------------------------------ yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbUnitTest.java | 39 --------------------------------------- yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseRedisUnitTest.java | 33 --------------------------------- yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/config/RedisTestConfiguration.java | 30 ------------------------------ yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppServiceTest.java | 245 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java | 20 -------------------- yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelServiceTest.java | 404 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantServiceTest.java | 193 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderServiceTest.java | 196 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java | 183 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreConvert.java | 22 ---------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayRefundCoreConvert.java | 23 ----------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java | 6 ------ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md | 1 - yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayAppDO.java | 62 -------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDO.java | 72 ------------------------------------------------------------------------ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java | 56 -------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyLogDO.java | 49 ------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyTaskDO.java | 99 --------------------------------------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java | 162 ------------------------------------------------------------------------------------------------------------------------------------------------------------------ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java | 82 ---------------------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java | 196 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java | 9 --------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayChannelCoreMapper.java | 20 -------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java | 9 --------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java | 30 ------------------------------ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java | 22 ---------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderExtensionCoreMapper.java | 20 -------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundCoreMapper.java | 23 ----------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/PayRedisKeyCoreConstants.java | 19 ------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/notify/PayNotifyLockCoreRedisDAO.java | 39 --------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java | 64 ---------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyStatusEnum.java | 32 -------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyTypeEnum.java | 28 ---------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderNotifyStatusEnum.java | 29 ----------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java | 29 ----------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundStatusEnum.java | 17 ----------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundTypeEnum.java | 29 ----------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java | 7 ------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java | 23 ----------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayChannelCoreService.java | 39 --------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java | 43 ------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayChannelCoreServiceImpl.java | 121 ------------------------------------------------------------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/PayNotifyCoreService.java | 29 ----------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java | 32 -------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/impl/PayNotifyCoreServiceImpl.java | 263 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayNotifyOrderReqVO.java | 28 ---------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayRefundOrderReqVO.java | 31 ------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/package-info.java | 6 ------ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java | 50 -------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java | 31 ------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java | 64 ---------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java | 47 ----------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java | 23 ----------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java | 51 --------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java | 24 ------------------------ yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java | 255 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java | 235 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java | 1 - yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/util/PaySeqUtils.java | 50 -------------------------------------------------- yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java | 13 +++++-------- yudao-module-pay/pom.xml | 25 +++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-api/pom.xml | 26 ++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java | 35 +++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/package-info.java | 1 + yudao-module-pay/yudao-module-pay-impl/pom.xml | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java | 37 +++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java | 12 ++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExcelVO.java | 40 ++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java | 41 +++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java | 45 +++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java | 43 +++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java | 19 +++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java | 17 +++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java | 21 +++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java | 37 +++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java | 21 +++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExcelVO.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java | 44 ++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java | 46 ++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java | 21 +++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java | 20 ++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java | 30 ++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java | 12 ++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExcelVO.java | 40 ++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java | 38 ++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java | 40 ++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java | 26 ++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java | 17 +++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java | 21 +++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExcelVO.java | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java | 36 ++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java | 23 +++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java | 12 ++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExcelVO.java | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java | 32 ++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java | 23 +++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java | 17 +++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java | 28 ++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java | 23 +++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/package-info.java | 1 + yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java | 47 +++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java | 34 ++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java | 22 ++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/package-info.java | 6 ++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/channel/PayChannelConvert.java | 38 ++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/merchant/PayMerchantConvert.java | 32 ++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/package-info.java | 6 ++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md | 1 + yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayAppDO.java | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayChannelDO.java | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayMerchantDO.java | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyLogDO.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderExtensionDO.java | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayAppMapper.java | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapper.java | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayMerchantMapper.java | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java | 9 +++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java | 30 ++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java | 20 ++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/PayRedisKeyCoreConstants.java | 19 +++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/notify/PayNotifyLockRedisDAO.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java | 32 ++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java | 28 ++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderNotifyStatusEnum.java | 29 +++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderStatusEnum.java | 29 +++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundStatusEnum.java | 17 +++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundTypeEnum.java | 29 +++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java | 29 +++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/package-info.java | 1 + yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/package-info.java | 10 ++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppService.java | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceImpl.java | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelService.java | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceImpl.java | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantService.java | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceImpl.java | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyService.java | 29 +++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java | 32 ++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java | 28 ++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java | 31 +++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/package-info.java | 6 ++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionService.java | 46 ++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionServiceImpl.java | 34 ++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java | 273 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderCreateReqDTO.java | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitReqDTO.java | 47 +++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitRespDTO.java | 23 +++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundRespDTO.java | 24 ++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/package-info.java | 1 + yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java | 261 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/util/PaySeqUtils.java | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceTest.java | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceTest.java | 392 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceTest.java | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/package-info.java | 1 + yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbAndRedisUnitTest.java | 47 +++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbUnitTest.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseRedisUnitTest.java | 31 +++++++++++++++++++++++++++++++ yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/RedisTestConfiguration.java | 30 ++++++++++++++++++++++++++++++ yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java | 25 ------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java | 122 -------------------------------------------------------------------------------------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java | 46 ---------------------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitReqVO.java | 28 ---------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitRespVO.java | 23 ----------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java | 34 ---------------------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java | 22 ---------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/order/PayRefundConvert.java | 23 ----------------------- yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/package-info.java | 6 ------ yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md | 1 - yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/package-info.java | 7 ------- 276 files changed, 8540 insertions(+), 8951 deletions(-) delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/PayAppController.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppBaseVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppCreateReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExcelVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExportReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageItemRespVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppRespVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateStatusReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/PayChannelController.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelBaseVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelCreateReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExcelVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExportReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelPageReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelRespVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelUpdateReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayOrderController.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayRefundController.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderBaseVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderDetailsRespVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExcelVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExportReqVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageItemRespVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageReqVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderRespVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundBaseVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundCreateReqVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundDetailsRespVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExcelVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExportReqVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageItemRespVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageReqVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundRespVO.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundUpdateReqVO.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/app/PayAppConvert.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/channel/PayChannelConvert.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/order/PayOrderConvert.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/package-info.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/refund/PayRefundConvert.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/app/PayAppMapper.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/channel/PayChannelMapper.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderExtensionMapper.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderMapper.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayRefundMapper.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/notify/PayNotifyJob.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/package-info.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/package-info.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppService.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/impl/PayAppServiceImpl.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelService.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java delete mode 100644 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderExtensionService.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderService.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayRefundService.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderExtensionServiceImpl.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderServiceImpl.java delete mode 100755 yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayRefundServiceImpl.java delete mode 100644 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbAndRedisUnitTest.java delete mode 100644 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbUnitTest.java delete mode 100644 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseRedisUnitTest.java delete mode 100644 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/config/RedisTestConfiguration.java delete mode 100644 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppServiceTest.java delete mode 100644 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java delete mode 100644 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelServiceTest.java delete mode 100644 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantServiceTest.java delete mode 100755 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderServiceTest.java delete mode 100755 yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreConvert.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayRefundCoreConvert.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayAppDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyLogDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyTaskDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayChannelCoreMapper.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderExtensionCoreMapper.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundCoreMapper.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/PayRedisKeyCoreConstants.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/notify/PayNotifyLockCoreRedisDAO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyStatusEnum.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyTypeEnum.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderNotifyStatusEnum.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundStatusEnum.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundTypeEnum.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayChannelCoreService.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayChannelCoreServiceImpl.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/PayNotifyCoreService.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/impl/PayNotifyCoreServiceImpl.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayNotifyOrderReqVO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayRefundOrderReqVO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/package-info.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java delete mode 100644 yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/util/PaySeqUtils.java create mode 100644 yudao-module-pay/pom.xml create mode 100644 yudao-module-pay/yudao-module-pay-api/pom.xml create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/package-info.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/pom.xml create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExcelVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExcelVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExcelVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExcelVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExcelVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/package-info.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/package-info.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/channel/PayChannelConvert.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/merchant/PayMerchantConvert.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/package-info.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayAppDO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayChannelDO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayMerchantDO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyLogDO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderExtensionDO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayAppMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayMerchantMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/PayRedisKeyCoreConstants.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/notify/PayNotifyLockRedisDAO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderNotifyStatusEnum.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderStatusEnum.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundStatusEnum.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundTypeEnum.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/package-info.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/package-info.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppService.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceImpl.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelService.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceImpl.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantService.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceImpl.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyService.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/package-info.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionService.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionServiceImpl.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderCreateReqDTO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitReqDTO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitRespDTO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundRespDTO.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/package-info.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/util/PaySeqUtils.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceTest.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceTest.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceTest.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/package-info.java create mode 100755 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbAndRedisUnitTest.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbUnitTest.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseRedisUnitTest.java create mode 100644 yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/RedisTestConfiguration.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitRespVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/order/PayRefundConvert.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/package-info.java delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md delete mode 100644 yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/package-info.java diff --git a/pom.xml b/pom.xml index f56f07d..e5294f7 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,7 @@ yudao-module-system yudao-module-infra yudao-module-tool + yudao-module-pay ${artifactId} diff --git a/yudao-admin-server/pom.xml b/yudao-admin-server/pom.xml index dd73b51..4eaef38 100644 --- a/yudao-admin-server/pom.xml +++ b/yudao-admin-server/pom.xml @@ -37,6 +37,11 @@ yudao-module-infra-impl ${revision} + + cn.iocoder.boot + yudao-module-pay-impl + ${revision} + @@ -71,11 +76,7 @@ - - - cn.iocoder.boot - yudao-spring-boot-starter-web - + org.springframework.boot @@ -83,34 +84,6 @@ true - - cn.iocoder.boot - yudao-spring-boot-starter-security - - - - - cn.iocoder.boot - yudao-spring-boot-starter-mybatis - - - - cn.iocoder.boot - yudao-spring-boot-starter-redis - - - - - cn.iocoder.boot - yudao-spring-boot-starter-job - - - - - cn.iocoder.boot - yudao-spring-boot-starter-mq - - cn.iocoder.boot @@ -128,24 +101,6 @@ spring-boot-admin-starter-server - - - cn.iocoder.boot - yudao-spring-boot-starter-test - test - - - - - cn.iocoder.boot - yudao-spring-boot-starter-excel - - - - org.apache.velocity - velocity-engine-core - - diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/PayAppController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/PayAppController.java deleted file mode 100644 index 3446243..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/PayAppController.java +++ /dev/null @@ -1,163 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*; -import cn.iocoder.yudao.adminserver.modules.pay.convert.app.PayAppConvert; -import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService; -import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService; -import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; -import java.io.IOException; -import java.util.*; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; - -@Slf4j -@Api(tags = "支付应用信息") -@RestController -@RequestMapping("/pay/app") -@Validated -public class PayAppController { - - @Resource - private PayAppService appService; - @Resource - private PayChannelService channelService; - @Resource - private PayMerchantService merchantService; - - @PostMapping("/create") - @ApiOperation("创建支付应用信息") - @PreAuthorize("@ss.hasPermission('pay:app:create')") - public CommonResult createApp(@Valid @RequestBody PayAppCreateReqVO createReqVO) { - return success(appService.createApp(createReqVO)); - } - - @PutMapping("/update") - @ApiOperation("更新支付应用信息") - @PreAuthorize("@ss.hasPermission('pay:app:update')") - public CommonResult updateApp(@Valid @RequestBody PayAppUpdateReqVO updateReqVO) { - appService.updateApp(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @ApiOperation("更新支付应用状态") - @PreAuthorize("@ss.hasPermission('pay:app:update')") - public CommonResult updateAppStatus(@Valid @RequestBody PayAppUpdateStatusReqVO updateReqVO) { - appService.updateAppStatus(updateReqVO.getId(), updateReqVO.getStatus()); - return success(true); - } - - @DeleteMapping("/delete") - @ApiOperation("删除支付应用信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:app:delete')") - public CommonResult deleteApp(@RequestParam("id") Long id) { - appService.deleteApp(id); - return success(true); - } - - @GetMapping("/get") - @ApiOperation("获得支付应用信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:app:query')") - public CommonResult getApp(@RequestParam("id") Long id) { - PayAppDO app = appService.getApp(id); - return success(PayAppConvert.INSTANCE.convert(app)); - } - - @GetMapping("/list") - @ApiOperation("获得支付应用信息列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) - @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") - @ApiOperation("获得支付应用信息分页") - @PreAuthorize("@ss.hasPermission('pay:app:query')") - public CommonResult> getAppPage(@Valid PayAppPageReqVO pageVO) { - // 得到应用分页列表 - PageResult pageResult = appService.getAppPage(pageVO); - if (CollUtil.isEmpty(pageResult.getList())) { - return success(new PageResult<>(pageResult.getTotal())); - } - - // 得到所有的应用编号,查出所有的通道 - 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 merchantIds = CollectionUtils.convertList(pageResult.getList(), PayAppDO::getMerchantId); - Map deptMap = merchantService.getMerchantMap(merchantIds); - - // 利用反射将通道数据复制到返回的数据结构中去 - List appList = new ArrayList<>(pageResult.getList().size()); - pageResult.getList().forEach(app -> { - // 写入应用信息的数据 - PayAppPageItemRespVO respVO = PayAppConvert.INSTANCE.pageConvert(app); - // 写入商户的数据 - respVO.setPayMerchant(PayAppConvert.INSTANCE.convert(deptMap.get(app.getMerchantId()))); - // 写入支付渠道信息的数据 - 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())); - } - - @GetMapping("/export-excel") - @ApiOperation("导出支付应用信息 Excel") - @PreAuthorize("@ss.hasPermission('pay:app:export')") - @OperateLog(type = EXPORT) - public void exportAppExcel(@Valid PayAppExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = appService.getAppList(exportReqVO); - // 导出 Excel - List datas = PayAppConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "支付应用信息.xls", "数据", PayAppExcelVO.class, datas); - } - - @GetMapping("/list-merchant-id") - @ApiOperation("根据商户 ID 查询支付应用信息") - @ApiImplicitParam(name = "merchantId", value = "商户ID", required = true, example = "1", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:merchant:query')") - public CommonResult> getMerchantListByName(@RequestParam String merchantId) { - List appListDO = appService.getListByMerchantId(merchantId); - return success(PayAppConvert.INSTANCE.convertList(appListDO)); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppBaseVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppBaseVO.java deleted file mode 100644 index 6ffe565..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppBaseVO.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import lombok.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; - -/** -* 支付应用信息 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class PayAppBaseVO { - - @ApiModelProperty(value = "应用名", required = true) - @NotNull(message = "应用名不能为空") - private String name; - - @ApiModelProperty(value = "开启状态", required = true) - @NotNull(message = "开启状态不能为空") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - - @ApiModelProperty(value = "支付结果的回调地址", required = true) - @NotNull(message = "支付结果的回调地址不能为空") - private String payNotifyUrl; - - @ApiModelProperty(value = "退款结果的回调地址", required = true) - @NotNull(message = "退款结果的回调地址不能为空") - private String refundNotifyUrl; - - @ApiModelProperty(value = "商户编号", required = true) - @NotNull(message = "商户编号不能为空") - private Long merchantId; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppCreateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppCreateReqVO.java deleted file mode 100644 index 3b0e69b..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppCreateReqVO.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; - -@ApiModel("支付应用信息创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayAppCreateReqVO extends PayAppBaseVO { - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExcelVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExcelVO.java deleted file mode 100644 index f81b53b..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExcelVO.java +++ /dev/null @@ -1,41 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; - -import com.alibaba.excel.annotation.ExcelProperty; - -/** - * 支付应用信息 Excel VO - * - * @author 芋艿 - */ -@Data -public class PayAppExcelVO { - - @ExcelProperty("应用编号") - private Long id; - - @ExcelProperty("应用名") - private String name; - - @ExcelProperty("开启状态") - private Integer status; - - @ExcelProperty("备注") - private String remark; - - @ExcelProperty("支付结果的回调地址") - private String payNotifyUrl; - - @ExcelProperty("退款结果的回调地址") - private String refundNotifyUrl; - - @ExcelProperty("商户编号") - private Long merchantId; - - @ExcelProperty("创建时间") - private Date createTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExportReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExportReqVO.java deleted file mode 100644 index b5d2844..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppExportReqVO.java +++ /dev/null @@ -1,41 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import org.springframework.format.annotation.DateTimeFormat; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel(value = "支付应用信息 Excel 导出 Request VO", description = "参数和 PayAppPageReqVO 是一致的") -@Data -public class PayAppExportReqVO { - - @ApiModelProperty(value = "应用名") - private String name; - - @ApiModelProperty(value = "开启状态") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - - @ApiModelProperty(value = "支付结果的回调地址") - private String payNotifyUrl; - - @ApiModelProperty(value = "退款结果的回调地址") - private String refundNotifyUrl; - - @ApiModelProperty(value = "商户名称") - private String merchantName; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageItemRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageItemRespVO.java deleted file mode 100644 index 6d8144a..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageItemRespVO.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; -import java.util.Set; - -/** - * 支付应用信息分页查询 Response VO - * - * @author aquan - */ -@ApiModel(value = "支付应用信息分页查询 Response VO", description = "相比于支付信息,还会多出应用渠道的开关信息") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayAppPageItemRespVO extends PayAppBaseVO { - - @ApiModelProperty(value = "应用编号", required = true) - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - - /** - * 所属商户 - */ - private PayMerchant payMerchant; - - @ApiModel("商户") - @Data - public static class PayMerchant { - - @ApiModelProperty(value = "商户编号", required = true, example = "1") - private Long id; - - @ApiModelProperty(value = "商户名称", required = true, example = "研发部") - private String name; - - } - - @ApiModelProperty(value = "渠道编码集合", required = true, example = "alipay_pc,alipay_wap...") - private Set channelCodes; - - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageReqVO.java deleted file mode 100644 index 62156e9..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppPageReqVO.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import org.springframework.format.annotation.DateTimeFormat; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel("支付应用信息分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayAppPageReqVO extends PageParam { - - @ApiModelProperty(value = "应用名") - private String name; - - @ApiModelProperty(value = "开启状态") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - - @ApiModelProperty(value = "支付结果的回调地址") - private String payNotifyUrl; - - @ApiModelProperty(value = "退款结果的回调地址") - private String refundNotifyUrl; - - @ApiModelProperty(value = "商户名称") - private String merchantName; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppRespVO.java deleted file mode 100644 index 565491f..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppRespVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; - -@ApiModel("支付应用信息 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayAppRespVO extends PayAppBaseVO { - - @ApiModelProperty(value = "应用编号", required = true) - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateReqVO.java deleted file mode 100644 index 426366f..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateReqVO.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; - -@ApiModel("支付应用信息更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayAppUpdateReqVO extends PayAppBaseVO { - - @ApiModelProperty(value = "应用编号", required = true) - @NotNull(message = "应用编号不能为空") - private Long id; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateStatusReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateStatusReqVO.java deleted file mode 100644 index 28a3218..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/app/vo/PayAppUpdateStatusReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotNull; - -@ApiModel("应用更新状态 Request VO") -@Data -public class PayAppUpdateStatusReqVO { - - @ApiModelProperty(value = "商户编号", required = true, example = "1024") - @NotNull(message = "商户编号不能为空") - private Long id; - - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举") - @NotNull(message = "状态不能为空") - private Integer status; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/PayChannelController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/PayChannelController.java deleted file mode 100644 index ae83ef9..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/PayChannelController.java +++ /dev/null @@ -1,129 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.channel; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*; -import cn.iocoder.yudao.adminserver.modules.pay.convert.channel.PayChannelConvert; -import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; -import java.io.IOException; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; - -/** - * 支付渠道 controller 组件 - * @author aquan - */ -@Api(tags = "支付渠道") -@RestController -@RequestMapping("/pay/channel") -@Validated -public class PayChannelController { - - @Resource - private PayChannelService channelService; - - - @PostMapping("/create") - @ApiOperation("创建支付渠道 ") - @PreAuthorize("@ss.hasPermission('pay:channel:create')") - public CommonResult createChannel(@Valid @RequestBody PayChannelCreateReqVO createReqVO) { - return success(channelService.createChannel(createReqVO)); - } - - @PutMapping("/update") - @ApiOperation("更新支付渠道 ") - @PreAuthorize("@ss.hasPermission('pay:channel:update')") - public CommonResult updateChannel(@Valid @RequestBody PayChannelUpdateReqVO updateReqVO) { - channelService.updateChannel(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @ApiOperation("删除支付渠道 ") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:channel:delete')") - public CommonResult deleteChannel(@RequestParam("id") Long id) { - channelService.deleteChannel(id); - return success(true); - } - - @GetMapping("/get") - @ApiOperation("获得支付渠道 ") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:channel:query')") - public CommonResult getChannel(@RequestParam("id") Long id) { - PayChannelDO channel = channelService.getChannel(id); - return success(PayChannelConvert.INSTANCE.convert(channel)); - } - - @GetMapping("/list") - @ApiOperation("获得支付渠道列表") - @ApiImplicitParam(name = "ids", value = "编号列表", - required = true, example = "1024,2048", dataTypeClass = List.class) - @PreAuthorize("@ss.hasPermission('pay:channel:query')") - public CommonResult> getChannelList(@RequestParam("ids") Collection ids) { - List list = channelService.getChannelList(ids); - return success(PayChannelConvert.INSTANCE.convertList(list)); - } - - @GetMapping("/page") - @ApiOperation("获得支付渠道分页") - @PreAuthorize("@ss.hasPermission('pay:channel:query')") - public CommonResult> getChannelPage(@Valid PayChannelPageReqVO pageVO) { - PageResult pageResult = channelService.getChannelPage(pageVO); - return success(PayChannelConvert.INSTANCE.convertPage(pageResult)); - } - - @GetMapping("/export-excel") - @ApiOperation("导出支付渠道Excel") - @PreAuthorize("@ss.hasPermission('pay:channel:export')") - @OperateLog(type = EXPORT) - public void exportChannelExcel(@Valid PayChannelExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = channelService.getChannelList(exportReqVO); - // 导出 Excel - List datas = PayChannelConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "支付渠道.xls", "数据", PayChannelExcelVO.class, datas); - } - - @GetMapping("/get-channel") - @ApiOperation("根据条件查询微信支付渠道") - @ApiImplicitParams({ - @ApiImplicitParam(name = "merchantId", value = "商户编号", - required = true, example = "1", dataTypeClass = Long.class), - @ApiImplicitParam(name = "appId", value = "应用编号", - required = true, example = "1", dataTypeClass = Long.class), - @ApiImplicitParam(name = "code", value = "支付渠道编码", - required = true, example = "wx_pub", dataTypeClass = String.class) - }) - @PreAuthorize("@ss.hasPermission('pay:channel:query')") - public CommonResult getChannel( - @RequestParam Long merchantId, @RequestParam Long appId, @RequestParam String code) { - - // 獲取渠道 - PayChannelDO channel = channelService.getChannelByConditions(merchantId, appId, code); - if (channel == null) { - return success(new PayChannelRespVO()); - } - // 拼凑数据 - PayChannelRespVO respVo = PayChannelConvert.INSTANCE.convert(channel); - return success(respVo); - } -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelBaseVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelBaseVO.java deleted file mode 100644 index 42a98b9..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelBaseVO.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; - -/** -* 支付渠道 - Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class PayChannelBaseVO { - - @ApiModelProperty(value = "渠道编码", required = true) - @NotNull(message = "渠道编码不能为空") - private String code; - - @ApiModelProperty(value = "开启状态", required = true) - @NotNull(message = "开启状态不能为空") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - - @ApiModelProperty(value = "渠道费率,单位:百分比", required = true) - @NotNull(message = "渠道费率,单位:百分比不能为空") - private Double feeRate; - - @ApiModelProperty(value = "商户编号", required = true) - @NotNull(message = "商户编号不能为空") - private Long merchantId; - - @ApiModelProperty(value = "应用编号", required = true) - @NotNull(message = "应用编号不能为空") - private Long appId; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelCreateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelCreateReqVO.java deleted file mode 100644 index a814b7b..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelCreateReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.NotBlank; - -@ApiModel("支付渠道 创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayChannelCreateReqVO extends PayChannelBaseVO { - - @ApiModelProperty(value = "通道配置的 json 字符串") - @NotBlank(message = "通道配置不能为空") - private String config; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExcelVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExcelVO.java deleted file mode 100644 index a461878..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExcelVO.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; - -import com.alibaba.excel.annotation.ExcelProperty; - -/** - * 支付渠道 - Excel VO - * - * @author 芋艿 - */ -@Data -public class PayChannelExcelVO { - - @ExcelProperty("商户编号") - private Long id; - - @ExcelProperty("渠道编码") - private String code; - - @ExcelProperty("开启状态") - private Integer status; - - @ExcelProperty("备注") - private String remark; - - @ExcelProperty("渠道费率,单位:百分比") - private Double feeRate; - - @ExcelProperty("商户编号") - private Long merchantId; - - @ExcelProperty("应用编号") - private Long appId; - - /** - * todo @芋艿 mapStruct 存在转换问题 - * java: Can't map property "PayClientConfig payChannelDO.config" to "String payChannelExcelVO.config". - * Consider to declare/implement a mapping method: "String map(PayClientConfig value)". - */ - /// @ExcelProperty("支付渠道配置") - /// private String config; - - @ExcelProperty("创建时间") - private Date createTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExportReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExportReqVO.java deleted file mode 100644 index 29e3acd..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelExportReqVO.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import org.springframework.format.annotation.DateTimeFormat; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel(value = "支付渠道 Excel 导出 Request VO", description = "参数和 PayChannelPageReqVO 是一致的") -@Data -public class PayChannelExportReqVO { - - @ApiModelProperty(value = "渠道编码") - private String code; - - @ApiModelProperty(value = "开启状态") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - - @ApiModelProperty(value = "渠道费率,单位:百分比") - private Double feeRate; - - @ApiModelProperty(value = "商户编号") - private Long merchantId; - - @ApiModelProperty(value = "应用编号") - private Long appId; - - @ApiModelProperty(value = "支付渠道配置") - private String config; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelPageReqVO.java deleted file mode 100644 index 83851f9..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelPageReqVO.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import org.springframework.format.annotation.DateTimeFormat; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel("支付渠道 分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayChannelPageReqVO extends PageParam { - - @ApiModelProperty(value = "渠道编码") - private String code; - - @ApiModelProperty(value = "开启状态") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - - @ApiModelProperty(value = "渠道费率,单位:百分比") - private Double feeRate; - - @ApiModelProperty(value = "商户编号") - private Long merchantId; - - @ApiModelProperty(value = "应用编号") - private Long appId; - - @ApiModelProperty(value = "支付渠道配置") - private String config; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelRespVO.java deleted file mode 100644 index 02873b9..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelRespVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; - -@ApiModel("支付渠道 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayChannelRespVO extends PayChannelBaseVO { - - @ApiModelProperty(value = "商户编号", required = true) - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - - @ApiModelProperty(value = "配置", required = true) - private String config; -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelUpdateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelUpdateReqVO.java deleted file mode 100644 index fdefc7b..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/channel/vo/PayChannelUpdateReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; - -@ApiModel("支付渠道 更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayChannelUpdateReqVO extends PayChannelBaseVO { - - @ApiModelProperty(value = "商户编号", required = true) - @NotNull(message = "商户编号不能为空") - private Long id; - - @ApiModelProperty(value = "通道配置的json字符串") - @NotBlank(message = "通道配置不能为空") - private String config; -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java deleted file mode 100644 index ae0235e..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/PayMerchantController.java +++ /dev/null @@ -1,116 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*; -import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert; -import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; -import java.io.IOException; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; - -@Api(tags = "支付商户信息") -@RestController -@RequestMapping("/pay/merchant") -@Validated -public class PayMerchantController { - - @Resource - private PayMerchantService merchantService; - - @PostMapping("/create") - @ApiOperation("创建支付商户信息") - @PreAuthorize("@ss.hasPermission('pay:merchant:create')") - public CommonResult createMerchant(@Valid @RequestBody PayMerchantCreateReqVO createReqVO) { - return success(merchantService.createMerchant(createReqVO)); - } - - @PutMapping("/update") - @ApiOperation("更新支付商户信息") - @PreAuthorize("@ss.hasPermission('pay:merchant:update')") - public CommonResult updateMerchant(@Valid @RequestBody PayMerchantUpdateReqVO updateReqVO) { - merchantService.updateMerchant(updateReqVO); - return success(true); - } - - @PutMapping("/update-status") - @ApiOperation("修改支付商户状态") - @PreAuthorize("@ss.hasPermission('pay:merchant:update')") - public CommonResult updateMerchantStatus(@Valid @RequestBody PayMerchantUpdateStatusReqVO reqVO) { - merchantService.updateMerchantStatus(reqVO.getId(), reqVO.getStatus()); - return success(true); - } - - @DeleteMapping("/delete") - @ApiOperation("删除支付商户信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:merchant:delete')") - public CommonResult deleteMerchant(@RequestParam("id") Long id) { - merchantService.deleteMerchant(id); - return success(true); - } - - @GetMapping("/get") - @ApiOperation("获得支付商户信息") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:merchant:query')") - public CommonResult getMerchant(@RequestParam("id") Long id) { - PayMerchantDO merchant = merchantService.getMerchant(id); - return success(PayMerchantConvert.INSTANCE.convert(merchant)); - } - - @GetMapping("/list-by-name") - @ApiOperation("根据商户名称获得支付商户信息列表") - @ApiImplicitParam(name = "name", value = "商户名称", example = "芋道", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:merchant:query')") - public CommonResult> getMerchantListByName(@RequestParam(required = false) String name) { - List merchantListDO = merchantService.getMerchantListByName(name); - return success(PayMerchantConvert.INSTANCE.convertList(merchantListDO)); - } - - @GetMapping("/list") - @ApiOperation("获得支付商户信息列表") - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) - @PreAuthorize("@ss.hasPermission('pay:merchant:query')") - public CommonResult> getMerchantList(@RequestParam("ids") Collection ids) { - List list = merchantService.getMerchantList(ids); - return success(PayMerchantConvert.INSTANCE.convertList(list)); - } - - @GetMapping("/page") - @ApiOperation("获得支付商户信息分页") - @PreAuthorize("@ss.hasPermission('pay:merchant:query')") - public CommonResult> getMerchantPage(@Valid PayMerchantPageReqVO pageVO) { - PageResult pageResult = merchantService.getMerchantPage(pageVO); - return success(PayMerchantConvert.INSTANCE.convertPage(pageResult)); - } - - @GetMapping("/export-excel") - @ApiOperation("导出支付商户信息 Excel") - @PreAuthorize("@ss.hasPermission('pay:merchant:export')") - @OperateLog(type = EXPORT) - public void exportMerchantExcel(@Valid PayMerchantExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - List list = merchantService.getMerchantList(exportReqVO); - // 导出 Excel - List datas = PayMerchantConvert.INSTANCE.convertList02(list); - ExcelUtils.write(response, "支付商户信息.xls", "数据", PayMerchantExcelVO.class, datas); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java deleted file mode 100644 index ed7b69a..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantBaseVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotNull; - -/** -* 支付商户信息 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class PayMerchantBaseVO { - - @ApiModelProperty(value = "商户全称", required = true) - @NotNull(message = "商户全称不能为空") - private String name; - - @ApiModelProperty(value = "商户简称", required = true) - @NotNull(message = "商户简称不能为空") - private String shortName; - - @ApiModelProperty(value = "开启状态", required = true) - @NotNull(message = "开启状态不能为空") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java deleted file mode 100644 index 2128de8..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantCreateReqVO.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; - -@ApiModel("支付商户信息创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayMerchantCreateReqVO extends PayMerchantBaseVO { - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java deleted file mode 100644 index cb229fb..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExcelVO.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo; - -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; -import com.alibaba.excel.annotation.ExcelProperty; -import lombok.Data; - -import java.util.Date; - -/** - * 支付商户信息 Excel VO - * - * @author 芋艿 - */ -@Data -public class PayMerchantExcelVO { - - @ExcelProperty("商户编号") - private Long id; - - @ExcelProperty("商户号") - private String no; - - @ExcelProperty("商户全称") - private String name; - - @ExcelProperty("商户简称") - private String shortName; - - @ExcelProperty(value = "开启状态",converter = DictConvert.class) - @DictFormat("sys_common_status") - private Integer status; - - @ExcelProperty("备注") - private String remark; - - @ExcelProperty("创建时间") - private Date createTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java deleted file mode 100644 index c6c3222..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantExportReqVO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import org.springframework.format.annotation.DateTimeFormat; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel(value = "支付商户信息 Excel 导出 Request VO", description = "参数和 PayMerchantPageReqVO 是一致的") -@Data -public class PayMerchantExportReqVO { - - @ApiModelProperty(value = "商户号") - private String no; - - @ApiModelProperty(value = "商户全称") - private String name; - - @ApiModelProperty(value = "商户简称") - private String shortName; - - @ApiModelProperty(value = "开启状态") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java deleted file mode 100644 index 8a66ac9..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantPageReqVO.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import org.springframework.format.annotation.DateTimeFormat; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel("支付商户信息分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayMerchantPageReqVO extends PageParam { - - @ApiModelProperty(value = "商户号") - private String no; - - @ApiModelProperty(value = "商户全称") - private String name; - - @ApiModelProperty(value = "商户简称") - private String shortName; - - @ApiModelProperty(value = "开启状态") - private Integer status; - - @ApiModelProperty(value = "备注") - private String remark; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java deleted file mode 100644 index d5b1943..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantRespVO.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -@ApiModel("支付商户信息 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayMerchantRespVO extends PayMerchantBaseVO { - - @ApiModelProperty(value = "商户编号", required = true) - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - - /** - * 商户号 - * 例如说,M233666999 - * 只有新增时插入,不允许修改 - */ - private String no; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java deleted file mode 100644 index 031d34f..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateReqVO.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo; - -import lombok.*; -import java.util.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; - -@ApiModel("支付商户信息更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayMerchantUpdateReqVO extends PayMerchantBaseVO { - - @ApiModelProperty(value = "商户编号", required = true) - @NotNull(message = "商户编号不能为空") - private Long id; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java deleted file mode 100644 index 6358769..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/merchant/vo/PayMerchantUpdateStatusReqVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotNull; - -@ApiModel("商户更新状态 Request VO") -@Data -public class PayMerchantUpdateStatusReqVO { - - @ApiModelProperty(value = "商户编号", required = true, example = "1024") - @NotNull(message = "商户编号不能为空") - private Long id; - - @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举") - @NotNull(message = "状态不能为空") - private Integer status; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayOrderController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayOrderController.java deleted file mode 100755 index 2ac44c6..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayOrderController.java +++ /dev/null @@ -1,177 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order; - -import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.*; -import cn.iocoder.yudao.adminserver.modules.pay.convert.order.PayOrderConvert; -import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService; -import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderExtensionService; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; - -/** - * 支付订单 controller 组件 - * - * @author aquan - */ -@Api(tags = "支付订单") -@RestController -@RequestMapping("/pay/order") -@Validated -public class PayOrderController { - - /** - * 订单 service 组件 - */ - @Resource - private PayOrderService orderService; - - /** - * 订单扩展 service 组件 - */ - @Resource - private PayOrderExtensionService orderExtensionService; - - /** - * 商户 service 组件 - */ - @Resource - private PayMerchantService merchantService; - - /** - * 应用 service 组件 - */ - @Resource - private PayAppService appService; - - @GetMapping("/get") - @ApiOperation("获得支付订单") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:order:query')") - public CommonResult getOrder(@RequestParam("id") Long id) { - PayOrderDO order = orderService.getOrder(id); - if (ObjectUtil.isNull(order)) { - return success(new PayOrderDetailsRespVO()); - } - - PayMerchantDO merchantDO = merchantService.getMerchant(order.getMerchantId()); - PayAppDO appDO = appService.getApp(order.getAppId()); - PayChannelEnum channelEnum = PayChannelEnum.getByCode(order.getChannelCode()); - - PayOrderDetailsRespVO respVO = PayOrderConvert.INSTANCE.orderDetailConvert(order); - respVO.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); - respVO.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); - respVO.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); - - PayOrderExtensionDO extensionDO = orderExtensionService.getOrderExtension(order.getSuccessExtensionId()); - if (ObjectUtil.isNotNull(extensionDO)) { - respVO.setPayOrderExtension(PayOrderConvert.INSTANCE.orderDetailExtensionConvert(extensionDO)); - } - - return success(respVO); - } - - @GetMapping("/page") - @ApiOperation("获得支付订单分页") - @PreAuthorize("@ss.hasPermission('pay:order:query')") - public CommonResult> getOrderPage(@Valid PayOrderPageReqVO pageVO) { - PageResult pageResult = orderService.getOrderPage(pageVO); - if (CollectionUtil.isEmpty(pageResult.getList())) { - return success(new PageResult<>(pageResult.getTotal())); - } - - // 处理商户ID数据 - Map merchantMap = merchantService.getMerchantMap( - CollectionUtils.convertList(pageResult.getList(), PayOrderDO::getMerchantId)); - // 处理应用ID数据 - Map appMap = appService.getAppMap( - CollectionUtils.convertList(pageResult.getList(), PayOrderDO::getAppId)); - - List pageList = new ArrayList<>(pageResult.getList().size()); - pageResult.getList().forEach(c -> { - PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId()); - PayAppDO appDO = appMap.get(c.getAppId()); - PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode()); - - PayOrderPageItemRespVO orderItem = PayOrderConvert.INSTANCE.pageConvertItemPage(c); - orderItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); - orderItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); - orderItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); - pageList.add(orderItem); - }); - return success(new PageResult<>(pageList, pageResult.getTotal())); - } - - @GetMapping("/export-excel") - @ApiOperation("导出支付订单Excel") - @PreAuthorize("@ss.hasPermission('pay:order:export')") - @OperateLog(type = EXPORT) - public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - - List list = orderService.getOrderList(exportReqVO); - if (CollectionUtil.isEmpty(list)) { - ExcelUtils.write(response, "支付订单.xls", "数据", - PayOrderExcelVO.class, new ArrayList<>()); - } - - // 处理商户ID数据 - Map merchantMap = merchantService.getMerchantMap( - CollectionUtils.convertList(list, PayOrderDO::getMerchantId)); - // 处理应用ID数据 - Map appMap = appService.getAppMap( - CollectionUtils.convertList(list, PayOrderDO::getAppId)); - // 处理扩展订单数据 - Map orderExtensionMap = orderExtensionService - .getOrderExtensionMap(CollectionUtils.convertList(list, PayOrderDO::getSuccessExtensionId)); - - List excelDatum = new ArrayList<>(list.size()); - list.forEach(c -> { - PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId()); - PayAppDO appDO = appMap.get(c.getAppId()); - PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode()); - PayOrderExtensionDO orderExtensionDO = orderExtensionMap.get(c.getSuccessExtensionId()); - - PayOrderExcelVO excelItem = PayOrderConvert.INSTANCE.excelConvert(c); - excelItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); - excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); - excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); - excelItem.setNo(ObjectUtil.isNotNull(orderExtensionDO) ? orderExtensionDO.getNo() : ""); - excelDatum.add(excelItem); - }); - - // 导出 Excel - ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelDatum); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayRefundController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayRefundController.java deleted file mode 100755 index 912d352..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/PayRefundController.java +++ /dev/null @@ -1,174 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order; - -import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.*; -import cn.iocoder.yudao.adminserver.modules.pay.convert.refund.PayRefundConvert; -import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService; -import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderService; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayRefundService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; - -/** - * 退款订单 Controller 组件 - * - * @author aquan - */ -@Api(tags = "退款订单") -@RestController -@RequestMapping("/pay/refund") -@Validated -public class PayRefundController { - - @Resource - private PayRefundService refundService; - - /** - * 商户 service 组件 - */ - @Resource - private PayMerchantService merchantService; - - /** - * 应用 service 组件 - */ - @Resource - private PayAppService appService; - - /** - * 订单 service 组件 - */ - @Resource - private PayOrderService orderService; - - - @GetMapping("/get") - @ApiOperation("获得退款订单") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('pay:refund:query')") - public CommonResult getRefund(@RequestParam("id") Long id) { - PayRefundDO refund = refundService.getRefund(id); - if (ObjectUtil.isNull(refund)) { - return success(new PayRefundDetailsRespVO()); - } - - PayMerchantDO merchantDO = merchantService.getMerchant(refund.getMerchantId()); - PayAppDO appDO = appService.getApp(refund.getAppId()); - PayChannelEnum channelEnum = PayChannelEnum.getByCode(refund.getChannelCode()); - PayOrderDO orderDO = orderService.getOrder(refund.getOrderId()); - - PayRefundDetailsRespVO refundDetail = PayRefundConvert.INSTANCE.refundDetailConvert(refund); - refundDetail.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); - refundDetail.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); - refundDetail.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); - refundDetail.setSubject(orderDO.getSubject()); - - return success(refundDetail); - } - - @GetMapping("/page") - @ApiOperation("获得退款订单分页") - @PreAuthorize("@ss.hasPermission('pay:refund:query')") - public CommonResult> getRefundPage(@Valid PayRefundPageReqVO pageVO) { - PageResult pageResult = refundService.getRefundPage(pageVO); - if (CollectionUtil.isEmpty(pageResult.getList())) { - return success(new PageResult<>(pageResult.getTotal())); - } - - // 处理商户ID数据 - Map merchantMap = merchantService.getMerchantMap( - CollectionUtils.convertList(pageResult.getList(), PayRefundDO::getMerchantId)); - // 处理应用ID数据 - Map appMap = appService.getAppMap( - CollectionUtils.convertList(pageResult.getList(), PayRefundDO::getAppId)); - List list = new ArrayList<>(pageResult.getList().size()); - pageResult.getList().forEach(c -> { - PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId()); - PayAppDO appDO = appMap.get(c.getAppId()); - PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode()); - - PayRefundPageItemRespVO item = PayRefundConvert.INSTANCE.pageItemConvert(c); - - item.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); - item.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); - item.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); - list.add(item); - }); - - return success(new PageResult<>(list, pageResult.getTotal())); - } - - @GetMapping("/export-excel") - @ApiOperation("导出退款订单 Excel") - @PreAuthorize("@ss.hasPermission('pay:refund:export')") - @OperateLog(type = EXPORT) - public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO, - HttpServletResponse response) throws IOException { - - List list = refundService.getRefundList(exportReqVO); - if (CollectionUtil.isEmpty(list)) { - ExcelUtils.write(response, "退款订单.xls", "数据", - PayRefundExcelVO.class, new ArrayList<>()); - } - - // 处理商户ID数据 - Map merchantMap = merchantService.getMerchantMap( - CollectionUtils.convertList(list, PayRefundDO::getMerchantId)); - // 处理应用ID数据 - Map appMap = appService.getAppMap( - CollectionUtils.convertList(list, PayRefundDO::getAppId)); - - List excelDatum = new ArrayList<>(list.size()); - // 处理商品名称数据 - Map orderMap = orderService.getOrderSubjectMap( - CollectionUtils.convertList(list, PayRefundDO::getOrderId)); - - list.forEach(c -> { - PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId()); - PayAppDO appDO = appMap.get(c.getAppId()); - PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode()); - - PayRefundExcelVO excelItem = PayRefundConvert.INSTANCE.excelConvert(c); - excelItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); - excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); - excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); - excelItem.setSubject(orderMap.get(c.getOrderId()).getSubject()); - - excelDatum.add(excelItem); - }); - - // 导出 Excel - ExcelUtils.write(response, "退款订单.xls", "数据", PayRefundExcelVO.class, excelDatum); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderBaseVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderBaseVO.java deleted file mode 100755 index 320125a..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderBaseVO.java +++ /dev/null @@ -1,108 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import javax.validation.constraints.NotNull; -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** - * 支付订单 - * Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - * - * @author aquan - */ -@Data -public class PayOrderBaseVO { - - @ApiModelProperty(value = "商户编号", required = true) - @NotNull(message = "商户编号不能为空") - private Long merchantId; - - @ApiModelProperty(value = "应用编号", required = true) - @NotNull(message = "应用编号不能为空") - private Long appId; - - @ApiModelProperty(value = "渠道编号") - private Long channelId; - - @ApiModelProperty(value = "渠道编码") - private String channelCode; - - @ApiModelProperty(value = "商户订单编号", required = true) - @NotNull(message = "商户订单编号不能为空") - private String merchantOrderId; - - @ApiModelProperty(value = "商品标题", required = true) - @NotNull(message = "商品标题不能为空") - private String subject; - - @ApiModelProperty(value = "商品描述", required = true) - @NotNull(message = "商品描述不能为空") - private String body; - - @ApiModelProperty(value = "异步通知地址", required = true) - @NotNull(message = "异步通知地址不能为空") - private String notifyUrl; - - @ApiModelProperty(value = "通知商户支付结果的回调状态", required = true) - @NotNull(message = "通知商户支付结果的回调状态不能为空") - private Integer notifyStatus; - - @ApiModelProperty(value = "支付金额,单位:分", required = true) - @NotNull(message = "支付金额,单位:分不能为空") - private Long amount; - - @ApiModelProperty(value = "渠道手续费,单位:百分比") - private Double channelFeeRate; - - @ApiModelProperty(value = "渠道手续金额,单位:分") - private Long channelFeeAmount; - - @ApiModelProperty(value = "支付状态", required = true) - @NotNull(message = "支付状态不能为空") - private Integer status; - - @ApiModelProperty(value = "用户 IP", required = true) - @NotNull(message = "用户 IP不能为空") - private String userIp; - - @ApiModelProperty(value = "订单失效时间", required = true) - @NotNull(message = "订单失效时间不能为空") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private Date expireTime; - - @ApiModelProperty(value = "订单支付成功时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private Date successTime; - - @ApiModelProperty(value = "订单支付通知时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private Date notifyTime; - - @ApiModelProperty(value = "支付成功的订单拓展单编号") - private Long successExtensionId; - - @ApiModelProperty(value = "退款状态", required = true) - @NotNull(message = "退款状态不能为空") - private Integer refundStatus; - - @ApiModelProperty(value = "退款次数", required = true) - @NotNull(message = "退款次数不能为空") - private Integer refundTimes; - - @ApiModelProperty(value = "退款总金额,单位:分", required = true) - @NotNull(message = "退款总金额,单位:分不能为空") - private Long refundAmount; - - @ApiModelProperty(value = "渠道用户编号") - private String channelUserId; - - @ApiModelProperty(value = "渠道订单号") - private String channelOrderNo; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderDetailsRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderDetailsRespVO.java deleted file mode 100644 index d85a9bc..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderDetailsRespVO.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -/** - * 支付订单详细信息,由支付订单和支付订单扩展信息组成 - * - * @author aquan - */ -@ApiModel("支付订单详细信息 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayOrderDetailsRespVO extends PayOrderBaseVO { - - @ApiModelProperty(value = "支付订单编号") - private Long id; - - @ApiModelProperty(value = "商户名称") - private String merchantName; - - @ApiModelProperty(value = "应用名称") - private String appName; - - @ApiModelProperty(value = "渠道编号名称") - private String channelCodeName; - - @ApiModelProperty(value = "创建时间") - private Date createTime; - - /** - * 支付订单扩展 - */ - private PayOrderExtension payOrderExtension; - - @Data - @ApiModel("支付订单扩展") - public static class PayOrderExtension { - - @ApiModelProperty(value = "支付订单号") - private String no; - - @ApiModelProperty(value = "支付异步通知的内容") - private String channelNotifyData; - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExcelVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExcelVO.java deleted file mode 100755 index f6836bc..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExcelVO.java +++ /dev/null @@ -1,91 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order; - -import cn.iocoder.yudao.module.system.enums.DictTypeConstants; -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; -import com.alibaba.excel.annotation.ExcelProperty; -import lombok.Data; - -import java.util.Date; - -/** - * 支付订单Excel VO - * - * @author aquan - */ -@Data -public class PayOrderExcelVO { - - @ExcelProperty("支付订单编号") - private Long id; - - @ExcelProperty(value = "商户名称") - private String merchantName; - - @ExcelProperty(value = "应用名称") - private String appName; - - @ExcelProperty("商品标题") - private String subject; - - @ExcelProperty("商户订单编号") - private String merchantOrderId; - - @ExcelProperty("渠道订单号") - private String channelOrderNo; - - @ExcelProperty(value = "支付订单号") - private String no; - - @ExcelProperty("支付金额,单位:元") - private String amount; - - @ExcelProperty("渠道手续金额,单位:元") - private String channelFeeAmount; - - @ExcelProperty("渠道手续费,单位:百分比") - private String channelFeeRate; - - @DictFormat(DictTypeConstants.PAY_ORDER_STATUS) - @ExcelProperty(value = "支付状态", converter = DictConvert.class) - private Integer status; - - @DictFormat(DictTypeConstants.PAY_ORDER_NOTIFY_STATUS) - @ExcelProperty(value = "通知商户支付结果的回调状态", converter = DictConvert.class) - private Integer notifyStatus; - - @ExcelProperty("异步通知地址") - private String notifyUrl; - - @ExcelProperty("创建时间") - private Date createTime; - - @ExcelProperty("订单支付成功时间") - private Date successTime; - - @ExcelProperty("订单失效时间") - private Date expireTime; - - @ExcelProperty("订单支付通知时间") - private Date notifyTime; - - @ExcelProperty(value = "渠道编号名称") - private String channelCodeName; - - @ExcelProperty("用户 IP") - private String userIp; - - @DictFormat(DictTypeConstants.PAY_ORDER_REFUND_STATUS) - @ExcelProperty(value = "退款状态", converter = DictConvert.class) - private Integer refundStatus; - - @ExcelProperty("退款次数") - private Integer refundTimes; - - @ExcelProperty("退款总金额,单位:元") - private String refundAmount; - - @ExcelProperty("商品描述") - private String body; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExportReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExportReqVO.java deleted file mode 100755 index 3445c86..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderExportReqVO.java +++ /dev/null @@ -1,112 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** - * 支付订单 Excel 导出 Request VO - * @author aquan - */ -@ApiModel(value = "支付订单 Excel 导出 Request VO", description = "参数和 PayOrderPageReqVO 是一致的") -@Data -public class PayOrderExportReqVO { - - @ApiModelProperty(value = "商户编号") - private Long merchantId; - - @ApiModelProperty(value = "应用编号") - private Long appId; - - @ApiModelProperty(value = "渠道编号") - private Long channelId; - - @ApiModelProperty(value = "渠道编码") - private String channelCode; - - @ApiModelProperty(value = "商户订单编号") - private String merchantOrderId; - - @ApiModelProperty(value = "商品标题") - private String subject; - - @ApiModelProperty(value = "商品描述") - private String body; - - @ApiModelProperty(value = "异步通知地址") - private String notifyUrl; - - @ApiModelProperty(value = "通知商户支付结果的回调状态") - private Integer notifyStatus; - - @ApiModelProperty(value = "支付金额,单位:分") - private Long amount; - - @ApiModelProperty(value = "渠道手续费,单位:百分比") - private Double channelFeeRate; - - @ApiModelProperty(value = "渠道手续金额,单位:分") - private Long channelFeeAmount; - - @ApiModelProperty(value = "支付状态") - private Integer status; - - @ApiModelProperty(value = "用户 IP") - private String userIp; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始订单失效时间") - private Date beginExpireTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束订单失效时间") - private Date endExpireTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始订单支付成功时间") - private Date beginSuccessTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束订单支付成功时间") - private Date endSuccessTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始订单支付通知时间") - private Date beginNotifyTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束订单支付通知时间") - private Date endNotifyTime; - - @ApiModelProperty(value = "支付成功的订单拓展单编号") - private Long successExtensionId; - - @ApiModelProperty(value = "退款状态") - private Integer refundStatus; - - @ApiModelProperty(value = "退款次数") - private Integer refundTimes; - - @ApiModelProperty(value = "退款总金额,单位:分") - private Long refundAmount; - - @ApiModelProperty(value = "渠道用户编号") - private String channelUserId; - - @ApiModelProperty(value = "渠道订单号") - private String channelOrderNo; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageItemRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageItemRespVO.java deleted file mode 100755 index b24b27a..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageItemRespVO.java +++ /dev/null @@ -1,41 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -/** - * 支付订单分页 Request VO - * - * @author aquan - */ -@ApiModel("支付订单分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayOrderPageItemRespVO extends PayOrderBaseVO { - - @ApiModelProperty(value = "支付订单编号", required = true) - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - - @ApiModelProperty(value = "商户名称") - private String merchantName; - - @ApiModelProperty(value = "应用名称") - private String appName; - - @ApiModelProperty(value = "渠道名称") - private String channelCodeName; - - @ApiModelProperty(value = "支付订单号") - private String no; - - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageReqVO.java deleted file mode 100755 index 07fa6a8..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderPageReqVO.java +++ /dev/null @@ -1,118 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** - * 支付订单分页 Request VO - * - * @author aquan - */ -@ApiModel("支付订单分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayOrderPageReqVO extends PageParam { - - @ApiModelProperty(value = "商户编号") - private Long merchantId; - - @ApiModelProperty(value = "应用编号") - private Long appId; - - @ApiModelProperty(value = "渠道编号") - private Long channelId; - - @ApiModelProperty(value = "渠道编码") - private String channelCode; - - @ApiModelProperty(value = "商户订单编号") - private String merchantOrderId; - - @ApiModelProperty(value = "商品标题") - private String subject; - - @ApiModelProperty(value = "商品描述") - private String body; - - @ApiModelProperty(value = "异步通知地址") - private String notifyUrl; - - @ApiModelProperty(value = "通知商户支付结果的回调状态") - private Integer notifyStatus; - - @ApiModelProperty(value = "支付金额,单位:分") - private Long amount; - - @ApiModelProperty(value = "渠道手续费,单位:百分比") - private Double channelFeeRate; - - @ApiModelProperty(value = "渠道手续金额,单位:分") - private Long channelFeeAmount; - - @ApiModelProperty(value = "支付状态") - private Integer status; - - @ApiModelProperty(value = "用户 IP") - private String userIp; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始订单失效时间") - private Date beginExpireTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束订单失效时间") - private Date endExpireTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始订单支付成功时间") - private Date beginSuccessTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束订单支付成功时间") - private Date endSuccessTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始订单支付通知时间") - private Date beginNotifyTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束订单支付通知时间") - private Date endNotifyTime; - - @ApiModelProperty(value = "支付成功的订单拓展单编号") - private Long successExtensionId; - - @ApiModelProperty(value = "退款状态") - private Integer refundStatus; - - @ApiModelProperty(value = "退款次数") - private Integer refundTimes; - - @ApiModelProperty(value = "退款总金额,单位:分") - private Long refundAmount; - - @ApiModelProperty(value = "渠道用户编号") - private String channelUserId; - - @ApiModelProperty(value = "渠道订单号") - private String channelOrderNo; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderRespVO.java deleted file mode 100755 index c466936..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/order/PayOrderRespVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -/** - * 支付订单 Response VO - * - * @author aquan - */ -@ApiModel("支付订单 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayOrderRespVO extends PayOrderBaseVO { - - @ApiModelProperty(value = "支付订单编号", required = true) - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundBaseVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundBaseVO.java deleted file mode 100755 index c8421b0..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundBaseVO.java +++ /dev/null @@ -1,110 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import javax.validation.constraints.NotNull; -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** -* 退款订单 Base VO,提供给添加、修改、详细的子 VO 使用 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 -*/ -@Data -public class PayRefundBaseVO { - - @ApiModelProperty(value = "商户编号", required = true) - @NotNull(message = "商户编号不能为空") - private Long merchantId; - - @ApiModelProperty(value = "应用编号", required = true) - @NotNull(message = "应用编号不能为空") - private Long appId; - - @ApiModelProperty(value = "渠道编号", required = true) - @NotNull(message = "渠道编号不能为空") - private Long channelId; - - @ApiModelProperty(value = "渠道编码", required = true) - @NotNull(message = "渠道编码不能为空") - private String channelCode; - - @ApiModelProperty(value = "支付订单编号 pay_order 表id", required = true) - @NotNull(message = "支付订单编号 pay_order 表id不能为空") - private Long orderId; - - @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段", required = true) - @NotNull(message = "交易订单号 pay_extension 表no 字段不能为空") - private String tradeNo; - - @ApiModelProperty(value = "商户订单编号(商户系统生成)", required = true) - @NotNull(message = "商户订单编号(商户系统生成)不能为空") - private String merchantOrderId; - - @ApiModelProperty(value = "商户退款订单号(商户系统生成)", required = true) - @NotNull(message = "商户退款订单号(商户系统生成)不能为空") - private String merchantRefundNo; - - @ApiModelProperty(value = "异步通知商户地址", required = true) - @NotNull(message = "异步通知商户地址不能为空") - private String notifyUrl; - - @ApiModelProperty(value = "通知商户退款结果的回调状态", required = true) - @NotNull(message = "通知商户退款结果的回调状态不能为空") - private Integer notifyStatus; - - @ApiModelProperty(value = "退款状态", required = true) - @NotNull(message = "退款状态不能为空") - private Integer status; - - @ApiModelProperty(value = "退款类型(部分退款,全部退款)", required = true) - @NotNull(message = "退款类型(部分退款,全部退款)不能为空") - private Integer type; - - @ApiModelProperty(value = "支付金额,单位分", required = true) - @NotNull(message = "支付金额,单位分不能为空") - private Long payAmount; - - @ApiModelProperty(value = "退款金额,单位分", required = true) - @NotNull(message = "退款金额,单位分不能为空") - private Long refundAmount; - - @ApiModelProperty(value = "退款原因", required = true) - @NotNull(message = "退款原因不能为空") - private String reason; - - @ApiModelProperty(value = "用户 IP") - private String userIp; - - @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应", required = true) - @NotNull(message = "渠道订单号,pay_order 中的channel_order_no 对应不能为空") - private String channelOrderNo; - - @ApiModelProperty(value = "渠道退款单号,渠道返回") - private String channelRefundNo; - - @ApiModelProperty(value = "渠道调用报错时,错误码") - private String channelErrorCode; - - @ApiModelProperty(value = "渠道调用报错时,错误信息") - private String channelErrorMsg; - - @ApiModelProperty(value = "支付渠道的额外参数") - private String channelExtras; - - @ApiModelProperty(value = "退款失效时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private Date expireTime; - - @ApiModelProperty(value = "退款成功时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private Date successTime; - - @ApiModelProperty(value = "退款通知时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private Date notifyTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundCreateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundCreateReqVO.java deleted file mode 100755 index 79b05c6..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundCreateReqVO.java +++ /dev/null @@ -1,12 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import lombok.*; -import io.swagger.annotations.*; - -@ApiModel("退款订单创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayRefundCreateReqVO extends PayRefundBaseVO { - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundDetailsRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundDetailsRespVO.java deleted file mode 100755 index d1d6739..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundDetailsRespVO.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.NotNull; -import java.util.Date; - -/** - * 退款订单详情 Response VO - * - * @author aquan - */ -@ApiModel("退款订单详情 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayRefundDetailsRespVO extends PayRefundBaseVO { - - @ApiModelProperty(value = "支付退款编号", required = true) - private Long id; - - @ApiModelProperty(value = "商户名称") - private String merchantName; - - @ApiModelProperty(value = "应用名称") - private String appName; - - @ApiModelProperty(value = "渠道编号名称") - private String channelCodeName; - - @NotNull(message = "商品标题不能为空") - private String subject; - - @ApiModelProperty(value = "创建时间") - private Date createTime; - - @ApiModelProperty(value = "更新时间") - private Date updateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExcelVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExcelVO.java deleted file mode 100755 index 793493e..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExcelVO.java +++ /dev/null @@ -1,88 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import cn.iocoder.yudao.module.system.enums.DictTypeConstants; -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; -import com.alibaba.excel.annotation.ExcelProperty; -import lombok.Data; - -import java.util.Date; - -/** - * 退款订单 Excel VO - * - * @author aquan - */ -@Data -public class PayRefundExcelVO { - - @ExcelProperty("支付退款编号") - private Long id; - - @ExcelProperty("商品名称") - private String subject; - - @ExcelProperty(value = "商户名称") - private String merchantName; - - @ExcelProperty(value = "应用名称") - private String appName; - - @ExcelProperty(value = "渠道编号名称") - private String channelCodeName; - - @ExcelProperty("交易订单号") - private String tradeNo; - - @ExcelProperty("商户订单编号") - private String merchantOrderId; - - @ExcelProperty("商户退款订单号") - private String merchantRefundNo; - - @ExcelProperty("异步通知商户地址") - private String notifyUrl; - - @DictFormat(DictTypeConstants.PAY_ORDER_NOTIFY_STATUS) - @ExcelProperty(value = "商户退款结果回调状态", converter = DictConvert.class) - private Integer notifyStatus; - - @DictFormat(DictTypeConstants.PAY_REFUND_ORDER_STATUS) - @ExcelProperty(value = "退款状态", converter = DictConvert.class) - private Integer status; - - @DictFormat(DictTypeConstants.PAY_REFUND_ORDER_TYPE) - @ExcelProperty(value = "退款类型", converter = DictConvert.class) - private Integer type; - - @ExcelProperty("支付金额,单位:元") - private String payAmount; - - @ExcelProperty("退款金额,单位:元") - private String refundAmount; - - @ExcelProperty("退款原因") - private String reason; - - @ExcelProperty("用户付款 IP") - private String userIp; - - @ExcelProperty("渠道订单号") - private String channelOrderNo; - - @ExcelProperty("渠道退款单号") - private String channelRefundNo; - - @ExcelProperty("创建时间") - private Date createTime; - - @ExcelProperty("退款成功时间") - private Date successTime; - - @ExcelProperty("退款通知时间") - private Date notifyTime; - - @ExcelProperty("退款失效时间") - private Date expireTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExportReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExportReqVO.java deleted file mode 100755 index 5a0e9c4..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundExportReqVO.java +++ /dev/null @@ -1,111 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel(value = "退款订单 Excel 导出 Request VO", description = "参数和 PayRefundPageReqVO 是一致的") -@Data -public class PayRefundExportReqVO { - - @ApiModelProperty(value = "商户编号") - private Long merchantId; - - @ApiModelProperty(value = "应用编号") - private Long appId; - - @ApiModelProperty(value = "渠道编号") - private Long channelId; - - @ApiModelProperty(value = "渠道编码") - private String channelCode; - - @ApiModelProperty(value = "支付订单编号 pay_order 表id") - private Long orderId; - - @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段") - private String tradeNo; - - @ApiModelProperty(value = "商户订单编号(商户系统生成)") - private String merchantOrderId; - - @ApiModelProperty(value = "商户退款订单号(商户系统生成)") - private String merchantRefundNo; - - @ApiModelProperty(value = "异步通知商户地址") - private String notifyUrl; - - @ApiModelProperty(value = "通知商户退款结果的回调状态") - private Integer notifyStatus; - - @ApiModelProperty(value = "退款状态") - private Integer status; - - @ApiModelProperty(value = "退款类型(部分退款,全部退款)") - private Integer type; - - @ApiModelProperty(value = "支付金额,单位分") - private Long payAmount; - - @ApiModelProperty(value = "退款金额,单位分") - private Long refundAmount; - - @ApiModelProperty(value = "退款原因") - private String reason; - - @ApiModelProperty(value = "用户 IP") - private String userIp; - - @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应") - private String channelOrderNo; - - @ApiModelProperty(value = "渠道退款单号,渠道返回") - private String channelRefundNo; - - @ApiModelProperty(value = "渠道调用报错时,错误码") - private String channelErrorCode; - - @ApiModelProperty(value = "渠道调用报错时,错误信息") - private String channelErrorMsg; - - @ApiModelProperty(value = "支付渠道的额外参数") - private String channelExtras; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始退款失效时间") - private Date beginExpireTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束退款失效时间") - private Date endExpireTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始退款成功时间") - private Date beginSuccessTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束退款成功时间") - private Date endSuccessTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始退款通知时间") - private Date beginNotifyTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束退款通知时间") - private Date endNotifyTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageItemRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageItemRespVO.java deleted file mode 100755 index 69e881b..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageItemRespVO.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -/** - * 退款订单分页查询 Response VO - * @author aquan - */ -@ApiModel("退款订单分页查询 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayRefundPageItemRespVO extends PayRefundBaseVO { - - @ApiModelProperty(value = "支付订单编号", required = true) - private Long id; - - @ApiModelProperty(value = "商户名称") - private String merchantName; - - @ApiModelProperty(value = "应用名称") - private String appName; - - @ApiModelProperty(value = "渠道名称") - private String channelCodeName; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageReqVO.java deleted file mode 100755 index 103a7a2..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundPageReqVO.java +++ /dev/null @@ -1,116 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@ApiModel("退款订单分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayRefundPageReqVO extends PageParam { - - @ApiModelProperty(value = "商户编号") - private Long merchantId; - - @ApiModelProperty(value = "应用编号") - private Long appId; - - @ApiModelProperty(value = "渠道编号") - private Long channelId; - - @ApiModelProperty(value = "渠道编码") - private String channelCode; - - @ApiModelProperty(value = "支付订单编号 pay_order 表id") - private Long orderId; - - @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段") - private String tradeNo; - - @ApiModelProperty(value = "商户订单编号(商户系统生成)") - private String merchantOrderId; - - @ApiModelProperty(value = "商户退款订单号(商户系统生成)") - private String merchantRefundNo; - - @ApiModelProperty(value = "异步通知商户地址") - private String notifyUrl; - - @ApiModelProperty(value = "通知商户退款结果的回调状态") - private Integer notifyStatus; - - @ApiModelProperty(value = "退款状态") - private Integer status; - - @ApiModelProperty(value = "退款类型(部分退款,全部退款)") - private Integer type; - - @ApiModelProperty(value = "支付金额,单位分") - private Long payAmount; - - @ApiModelProperty(value = "退款金额,单位分") - private Long refundAmount; - - @ApiModelProperty(value = "退款原因") - private String reason; - - @ApiModelProperty(value = "用户 IP") - private String userIp; - - @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应") - private String channelOrderNo; - - @ApiModelProperty(value = "渠道退款单号,渠道返回") - private String channelRefundNo; - - @ApiModelProperty(value = "渠道调用报错时,错误码") - private String channelErrorCode; - - @ApiModelProperty(value = "渠道调用报错时,错误信息") - private String channelErrorMsg; - - @ApiModelProperty(value = "支付渠道的额外参数") - private String channelExtras; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始退款失效时间") - private Date beginExpireTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束退款失效时间") - private Date endExpireTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始退款成功时间") - private Date beginSuccessTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束退款成功时间") - private Date endSuccessTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始退款通知时间") - private Date beginNotifyTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束退款通知时间") - private Date endNotifyTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "开始创建时间") - private Date beginCreateTime; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "结束创建时间") - private Date endCreateTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundRespVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundRespVO.java deleted file mode 100755 index 901a0fe..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundRespVO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -@ApiModel("退款订单 Response VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayRefundRespVO extends PayRefundBaseVO { - - @ApiModelProperty(value = "支付退款编号", required = true) - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundUpdateReqVO.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundUpdateReqVO.java deleted file mode 100755 index 8cb2dcf..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/controller/order/vo/refund/vo/PayRefundUpdateReqVO.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo; - -import lombok.*; -import io.swagger.annotations.*; -import javax.validation.constraints.*; - -@ApiModel("退款订单更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class PayRefundUpdateReqVO extends PayRefundBaseVO { - - @ApiModelProperty(value = "支付退款编号", required = true) - @NotNull(message = "支付退款编号不能为空") - private Long id; - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/app/PayAppConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/app/PayAppConvert.java deleted file mode 100644 index c7e1746..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/app/PayAppConvert.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.convert.app; - -import java.util.*; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.*; - -/** - * 支付应用信息 Convert - * - * @author 芋艿 - */ -@Mapper -public interface PayAppConvert { - - PayAppConvert INSTANCE = Mappers.getMapper(PayAppConvert.class); - - PayAppPageItemRespVO pageConvert (PayAppDO bean); - - PayAppPageItemRespVO.PayMerchant convert(PayMerchantDO bean); - - PayAppDO convert(PayAppCreateReqVO bean); - - PayAppDO convert(PayAppUpdateReqVO bean); - - PayAppRespVO convert(PayAppDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - List convertList02(List list); - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/channel/PayChannelConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/channel/PayChannelConvert.java deleted file mode 100644 index ee0473c..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/channel/PayChannelConvert.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.convert.channel; - -import java.util.*; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*; - -/** - * 支付渠道 - Convert - * - * @author 芋艿 - */ -@Mapper -public interface PayChannelConvert { - - PayChannelConvert INSTANCE = Mappers.getMapper(PayChannelConvert.class); - - @Mapping(target = "config",ignore = true) - PayChannelDO convert(PayChannelCreateReqVO bean); - - @Mapping(target = "config",ignore = true) - PayChannelDO convert(PayChannelUpdateReqVO bean); - - @Mapping(target = "config",expression = "java(cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString(bean.getConfig()))") - PayChannelRespVO convert(PayChannelDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - List convertList02(List list); - - - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java deleted file mode 100644 index 9483ff1..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/merchant/PayMerchantConvert.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.convert.merchant; - -import java.util.*; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.*; - -/** - * 支付商户信息 Convert - * - * @author 芋艿 - */ -@Mapper -public interface PayMerchantConvert { - - PayMerchantConvert INSTANCE = Mappers.getMapper(PayMerchantConvert.class); - - PayMerchantDO convert(PayMerchantCreateReqVO bean); - - PayMerchantDO convert(PayMerchantUpdateReqVO bean); - - PayMerchantRespVO convert(PayMerchantDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - List convertList02(List list); - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/order/PayOrderConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/order/PayOrderConvert.java deleted file mode 100755 index 308298a..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/order/PayOrderConvert.java +++ /dev/null @@ -1,104 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.convert.order; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderDetailsRespVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExcelVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageItemRespVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderRespVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.List; - -/** - * 支付订单 Convert - * - * @author aquan - */ -@Mapper -public interface PayOrderConvert { - - PayOrderConvert INSTANCE = Mappers.getMapper(PayOrderConvert.class); - - - - PayOrderRespVO convert(PayOrderDO bean); - - /** - * 订单DO 转换为 详细订单 RespVO - * - * @param bean 订单DO - * @return 详细订单 RespVO - */ - PayOrderDetailsRespVO orderDetailConvert(PayOrderDO bean); - - /** - * 订单扩展DO 转换为 详细订单扩展 RespVO - * - * @param bean 订单扩展DO - * @return 详细订单扩展 RespVO - */ - PayOrderDetailsRespVO.PayOrderExtension orderDetailExtensionConvert(PayOrderExtensionDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - List convertList02(List list); - - /** - * 订单DO转自定义分页对象 - * - * @param bean 订单DO - * @return 分页对象 - */ - PayOrderPageItemRespVO pageConvertItemPage(PayOrderDO bean); - - /** - * 订单DO 转 订单导出excel VO - * - * @param bean 订单 DO - * @return 订单导出excel VO - */ - default PayOrderExcelVO excelConvert(PayOrderDO bean) { - if (bean == null) { - return null; - } - - PayOrderExcelVO payOrderExcelVO = new PayOrderExcelVO(); - - payOrderExcelVO.setId(bean.getId()); - payOrderExcelVO.setSubject(bean.getSubject()); - payOrderExcelVO.setMerchantOrderId(bean.getMerchantOrderId()); - payOrderExcelVO.setChannelOrderNo(bean.getChannelOrderNo()); - payOrderExcelVO.setStatus(bean.getStatus()); - payOrderExcelVO.setNotifyStatus(bean.getNotifyStatus()); - payOrderExcelVO.setNotifyUrl(bean.getNotifyUrl()); - payOrderExcelVO.setCreateTime(bean.getCreateTime()); - payOrderExcelVO.setSuccessTime(bean.getSuccessTime()); - payOrderExcelVO.setExpireTime(bean.getExpireTime()); - payOrderExcelVO.setNotifyTime(bean.getNotifyTime()); - payOrderExcelVO.setUserIp(bean.getUserIp()); - payOrderExcelVO.setRefundStatus(bean.getRefundStatus()); - payOrderExcelVO.setRefundTimes(bean.getRefundTimes()); - payOrderExcelVO.setBody(bean.getBody()); - - BigDecimal multiple = new BigDecimal(100); - - payOrderExcelVO.setAmount(BigDecimal.valueOf(bean.getAmount()) - .divide(multiple, 2, RoundingMode.HALF_UP).toString()); - - payOrderExcelVO.setChannelFeeAmount(BigDecimal.valueOf(bean.getChannelFeeAmount()) - .divide(multiple, 2, RoundingMode.HALF_UP).toString()); - payOrderExcelVO.setChannelFeeRate(java.math.BigDecimal.valueOf(bean.getChannelFeeRate()) - .multiply(multiple).toString()); - payOrderExcelVO.setRefundAmount(BigDecimal.valueOf(bean.getRefundAmount()) - .divide(multiple, 2, RoundingMode.HALF_UP).toString()); - - return payOrderExcelVO; - } -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/package-info.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/package-info.java deleted file mode 100644 index da39733..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 提供 POJO 类的实体转换 - * - * 目前使用 MapStruct 框架 - */ -package cn.iocoder.yudao.adminserver.modules.pay.convert; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/refund/PayRefundConvert.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/refund/PayRefundConvert.java deleted file mode 100755 index 8f5ee66..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/refund/PayRefundConvert.java +++ /dev/null @@ -1,90 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.convert.refund; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.*; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.math.BigDecimal; -import java.math.RoundingMode; -import java.util.List; - -/** - * 退款订单 Convert - * - * @author aquan - */ -@Mapper -public interface PayRefundConvert { - - PayRefundConvert INSTANCE = Mappers.getMapper(PayRefundConvert.class); - - PayRefundDO convert(PayRefundCreateReqVO bean); - - PayRefundDO convert(PayRefundUpdateReqVO bean); - - PayRefundRespVO convert(PayRefundDO bean); - - /** - * 退款订单 DO 转 退款详情订单 VO - * - * @param bean 退款订单 DO - * @return 退款详情订单 VO - */ - PayRefundDetailsRespVO refundDetailConvert(PayRefundDO bean); - - /** - * 退款订单DO 转 分页退款条目VO - * - * @param bean 退款订单DO - * @return 分页退款条目VO - */ - PayRefundPageItemRespVO pageItemConvert(PayRefundDO bean); - - List convertList(List list); - - PageResult convertPage(PageResult page); - - List convertList02(List list); - - /** - * 退款订单DO 转 导出excel VO - * - * @param bean 退款订单DO - * @return 导出 excel VO - */ - default PayRefundExcelVO excelConvert(PayRefundDO bean) { - if (bean == null) { - return null; - } - - PayRefundExcelVO payRefundExcelVO = new PayRefundExcelVO(); - - payRefundExcelVO.setId(bean.getId()); - payRefundExcelVO.setTradeNo(bean.getTradeNo()); - payRefundExcelVO.setMerchantOrderId(bean.getMerchantOrderId()); - payRefundExcelVO.setMerchantRefundNo(bean.getMerchantRefundNo()); - payRefundExcelVO.setNotifyUrl(bean.getNotifyUrl()); - payRefundExcelVO.setNotifyStatus(bean.getNotifyStatus()); - payRefundExcelVO.setStatus(bean.getStatus()); - payRefundExcelVO.setType(bean.getType()); - payRefundExcelVO.setReason(bean.getReason()); - payRefundExcelVO.setUserIp(bean.getUserIp()); - payRefundExcelVO.setChannelOrderNo(bean.getChannelOrderNo()); - payRefundExcelVO.setChannelRefundNo(bean.getChannelRefundNo()); - payRefundExcelVO.setExpireTime(bean.getExpireTime()); - payRefundExcelVO.setSuccessTime(bean.getSuccessTime()); - payRefundExcelVO.setNotifyTime(bean.getNotifyTime()); - payRefundExcelVO.setCreateTime(bean.getCreateTime()); - - BigDecimal multiple = new BigDecimal(100); - payRefundExcelVO.setPayAmount(BigDecimal.valueOf(bean.getPayAmount()) - .divide(multiple, 2, RoundingMode.HALF_UP).toString()); - payRefundExcelVO.setRefundAmount(BigDecimal.valueOf(bean.getRefundAmount()) - .divide(multiple, 2, RoundingMode.HALF_UP).toString()); - - return payRefundExcelVO; - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md deleted file mode 100644 index 8153487..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/app/PayAppMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/app/PayAppMapper.java deleted file mode 100644 index c6e3b38..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/app/PayAppMapper.java +++ /dev/null @@ -1,83 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 支付应用信息 Mapper - * - * @author aquan - */ -@Mapper -public interface PayAppMapper extends BaseMapperX { - - /** - * 分页查询 - * - * @param reqVO 支付应用信息分页查询条件 - * @param merchantIds 商户 ID 集合 - * @return 支付应用信息 - */ - default PageResult selectPage(PayAppPageReqVO reqVO, Collection merchantIds) { - 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()) - .inIfPresent("merchant_id", merchantIds) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id")); - } - - /** - * 列表查询 - * - * @param reqVO 支付应用信息 Excel 导出查询条件 - * @param merchantIds 商户 ID 集合 - * @return 支付应用信息 - */ - default List selectList(PayAppExportReqVO reqVO, Collection merchantIds) { - return selectList(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()) - .inIfPresent("merchant_id", merchantIds) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id")); - } - - /** - * 根据 商户 ID 查询支付应用信息 - * - * @param merchantId 商户 ID - * @return 支付应用信息列表 - */ - default List getListByMerchantId(String merchantId) { - return selectList(new LambdaQueryWrapper() - .select(PayAppDO::getId, PayAppDO::getName) - .eq(PayAppDO::getMerchantId, merchantId)); - } - - /** - * 根据商户号统计存在的支付应用数量 - * - * @param merchantId 商户 ID - * @return 支付应用数量 - */ - default Long selectCount(Long merchantId) { - return selectCount(new LambdaQueryWrapper().eq(PayAppDO::getMerchantId, merchantId)); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/channel/PayChannelMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/channel/PayChannelMapper.java deleted file mode 100644 index 54a4829..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/channel/PayChannelMapper.java +++ /dev/null @@ -1,91 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelPageReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 支付渠道 - Mapper - * - * @author 芋艿 - */ -@Mapper -public interface PayChannelMapper extends BaseMapperX { - - default PageResult selectPage(PayChannelPageReqVO reqVO) { - return selectPage(reqVO, new QueryWrapperX() - .eqIfPresent("code", reqVO.getCode()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("remark", reqVO.getRemark()) - .eqIfPresent("fee_rate", reqVO.getFeeRate()) - .eqIfPresent("merchant_id", reqVO.getMerchantId()) - .eqIfPresent("app_id", reqVO.getAppId()) - // .eqIfPresent("config", reqVO.getConfig()) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id") ); - } - - default List selectList(PayChannelExportReqVO reqVO) { - return selectList(new QueryWrapperX() - .eqIfPresent("code", reqVO.getCode()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("remark", reqVO.getRemark()) - .eqIfPresent("fee_rate", reqVO.getFeeRate()) - .eqIfPresent("merchant_id", reqVO.getMerchantId()) - .eqIfPresent("app_id", reqVO.getAppId()) - // .eqIfPresent("config", reqVO.getConfig()) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id") ); - } - - /** - * 根据条件获取通道数量 - * - * @param merchantId 商户编号 - * @param appid 应用编号 - * @param code 通道编码 - * @return 数量 - */ - default Integer selectCount(Long merchantId, Long appid, String code) { - return this.selectCount(new QueryWrapper().lambda() - .eq(PayChannelDO::getMerchantId, merchantId) - .eq(PayChannelDO::getAppId, appid) - .eq(PayChannelDO::getCode, code)).intValue(); - } - - /** - * 根据条件获取通道 - * - * @param merchantId 商户编号 - * @param appid 应用编号 - * @param code 通道编码 - * @return 数量 - */ - default PayChannelDO selectOne(Long merchantId, Long appid, String code) { - return this.selectOne((new QueryWrapper().lambda() - .eq(PayChannelDO::getMerchantId, merchantId) - .eq(PayChannelDO::getAppId, appid) - .eq(PayChannelDO::getCode, code) - )); - } - - /** - * 根据支付应用ID集合获得支付渠道列表 - * - * @param appIds 应用编号集合 - * @return 支付渠道列表 - */ - default List getChannelListByAppIds(Collection appIds){ - return this.selectList(new QueryWrapper().lambda() - .in(PayChannelDO::getAppId, appIds)); - } -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java deleted file mode 100644 index f143b18..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/merchant/PayMerchantMapper.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -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 org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * 支付商户信息 Mapper - * - * @author 芋艿 - */ -@Mapper -public interface PayMerchantMapper extends BaseMapperX { - - default PageResult selectPage(PayMerchantPageReqVO reqVO) { - return selectPage(reqVO, new QueryWrapperX() - .likeIfPresent("no", reqVO.getNo()) - .likeIfPresent("name", reqVO.getName()) - .likeIfPresent("short_name", reqVO.getShortName()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("remark", reqVO.getRemark()) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id")); - } - - default List selectList(PayMerchantExportReqVO reqVO) { - return selectList(new QueryWrapperX() - .likeIfPresent("no", reqVO.getNo()) - .likeIfPresent("name", reqVO.getName()) - .likeIfPresent("short_name", reqVO.getShortName()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("remark", reqVO.getRemark()) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id")); - } - - /** - * 根据商户名称模糊查询商户集合 - * - * @param merchantName 商户名称 - * @return 商户集合 - */ - default List getMerchantListByName(String merchantName) { - return this.selectList(new QueryWrapperX() - .likeIfPresent("name", merchantName)); - } -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderExtensionMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderExtensionMapper.java deleted file mode 100755 index 47baabb..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderExtensionMapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -/** - * 支付订单 Mapper - * - * @author aquan - */ -@Mapper -public interface PayOrderExtensionMapper extends BaseMapperX { - - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderMapper.java deleted file mode 100755 index 1fb9e87..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayOrderMapper.java +++ /dev/null @@ -1,79 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Collection; -import java.util.List; - -/** - * 支付订单 Mapper 组件 - * - * @author aquan - */ -@Mapper -public interface PayOrderMapper extends BaseMapperX { - - default PageResult selectPage(PayOrderPageReqVO reqVO) { - return selectPage(reqVO, new QueryWrapperX() - .eqIfPresent("merchant_id", reqVO.getMerchantId()) - .eqIfPresent("app_id", reqVO.getAppId()) - .eqIfPresent("channel_id", reqVO.getChannelId()) - .eqIfPresent("channel_code", reqVO.getChannelCode()) - .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId()) - .eqIfPresent("notify_status", reqVO.getNotifyStatus()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("refund_status", reqVO.getRefundStatus()) - .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo()) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id")); - } - - default List selectList(PayOrderExportReqVO reqVO) { - return selectList(new QueryWrapperX() - .eqIfPresent("merchant_id", reqVO.getMerchantId()) - .eqIfPresent("app_id", reqVO.getAppId()) - .eqIfPresent("channel_id", reqVO.getChannelId()) - .eqIfPresent("channel_code", reqVO.getChannelCode()) - .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId()) - .eqIfPresent("notify_status", reqVO.getNotifyStatus()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("refund_status", reqVO.getRefundStatus()) - .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo()) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id")); - } - - /** - * 根据订单 ID 集合查询订单商品名称 - * - * @param idList 订单 ID 集合 - * @return 只包含商品名称和标题的订单集合对象 - */ - default List findByIdListQueryOrderSubject(Collection idList) { - return selectList(new LambdaQueryWrapper() - .select(PayOrderDO::getId, PayOrderDO::getSubject) - .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)); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayRefundMapper.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayRefundMapper.java deleted file mode 100755 index 2fd3f22..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/dal/mysql/order/PayRefundMapper.java +++ /dev/null @@ -1,61 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -/** - * 退款订单 Mapper - * - * @author aquan - */ -@Mapper -public interface PayRefundMapper extends BaseMapperX { - - default PageResult selectPage(PayRefundPageReqVO reqVO) { - return selectPage(reqVO, new QueryWrapperX() - .eqIfPresent("merchant_id", reqVO.getMerchantId()) - .eqIfPresent("app_id", reqVO.getAppId()) - .eqIfPresent("channel_code", reqVO.getChannelCode()) - .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo()) - .eqIfPresent("type", reqVO.getType()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("notify_status", reqVO.getNotifyStatus()) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id")); - } - - default List selectList(PayRefundExportReqVO reqVO) { - return selectList(new QueryWrapperX() - .eqIfPresent("merchant_id", reqVO.getMerchantId()) - .eqIfPresent("app_id", reqVO.getAppId()) - .eqIfPresent("channel_code", reqVO.getChannelCode()) - .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo()) - .eqIfPresent("type", reqVO.getType()) - .eqIfPresent("status", reqVO.getStatus()) - .eqIfPresent("notify_status", reqVO.getNotifyStatus()) - .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) - .orderByDesc("id")); - } - - /** - * 查询符合的订单数量 - * - * @param appId 应用编号 - * @param status 订单状态 - * @return 条数 - */ - default Long selectCount(Long appId, Integer status) { - - return selectCount(new LambdaQueryWrapper() - .eq(PayRefundDO::getAppId, appId) - .eq(PayRefundDO::getStatus, status)); - } -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java deleted file mode 100644 index df39d9e..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/enums/PayErrorCodeConstants.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.enums; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/notify/PayNotifyJob.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/notify/PayNotifyJob.java deleted file mode 100644 index 58685f1..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/notify/PayNotifyJob.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.job.notify; - -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService; -import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; - -import javax.annotation.Resource; - -/** - * 支付通知 Job - * 通过不断扫描待通知的 PayNotifyTaskDO 记录,回调业务线的回调接口 - * - * @author 芋道源码 - */ -@Component -@Slf4j -public class PayNotifyJob implements JobHandler { - - @Resource - private PayNotifyCoreService payNotifyCoreService; - - @Override - public String execute(String param) throws Exception { - int notifyCount = payNotifyCoreService.executeNotify(); - return String.format("执行支付通知 %s 个", notifyCount); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/package-info.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/package-info.java deleted file mode 100644 index 3db5697..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/job/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.job; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/package-info.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/package-info.java deleted file mode 100644 index a113b9b..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * pay 包下,我们放支付业务,提供业务的支付能力。 - * 例如说:商户、应用、支付、退款等等 - * - * 缩写:pay - */ -package cn.iocoder.yudao.adminserver.modules.pay; diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppService.java deleted file mode 100644 index da83ca8..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppService.java +++ /dev/null @@ -1,103 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.app; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppCreateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppUpdateReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * 支付应用信息 Service 接口 - * - * @author 芋艿 - */ -public interface PayAppService { - - /** - * 创建支付应用信息 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createApp(@Valid PayAppCreateReqVO createReqVO); - - /** - * 更新支付应用信息 - * - * @param updateReqVO 更新信息 - */ - void updateApp(@Valid PayAppUpdateReqVO updateReqVO); - - /** - * 删除支付应用信息 - * - * @param id 编号 - */ - void deleteApp(Long id); - - /** - * 获得支付应用信息 - * - * @param id 编号 - * @return 支付应用信息 - */ - PayAppDO getApp(Long id); - - /** - * 获得支付应用信息列表 - * - * @param ids 编号 - * @return 支付应用信息列表 - */ - List getAppList(Collection ids); - - /** - * 获得支付应用信息分页 - * - * @param pageReqVO 分页查询 - * @return 支付应用信息分页 - */ - PageResult getAppPage(PayAppPageReqVO pageReqVO); - - /** - * 获得支付应用信息列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 支付应用信息列表 - */ - List getAppList(PayAppExportReqVO exportReqVO); - - /** - * 修改应用信息状态 - * - * @param id 应用编号 - * @param status 状态{@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} - */ - void updateAppStatus(Long id, Integer status); - - /** - * 根据商户 ID 获得支付应用信息列表, - * - * @param merchantId 商户 ID - * @return 支付应用信息列表 - */ - List getListByMerchantId(String merchantId); - - /** - * 获得指定编号的商户 Map - * - * @param appIdList 应用编号集合 - * @return 商户 Map - */ - default Map getAppMap(Collection appIdList) { - List list = this.getAppList(appIdList); - return CollectionUtils.convertMap(list, PayAppDO::getId); - } -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/impl/PayAppServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/impl/PayAppServiceImpl.java deleted file mode 100644 index bb6e765..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/impl/PayAppServiceImpl.java +++ /dev/null @@ -1,189 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.app.impl; - -import cn.hutool.core.collection.CollectionUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppCreateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppUpdateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.convert.app.PayAppConvert; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app.PayAppMapper; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderMapper; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayRefundMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.app.PayAppService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import com.google.common.annotations.VisibleForTesting; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.*; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; - -/** - * 支付应用信息 Service 实现类 - * - * @author aquan - */ -@Service -@Validated -public class PayAppServiceImpl implements PayAppService { - - @Resource - private PayAppMapper appMapper; - - @Resource - private PayMerchantMapper merchantMapper; - - @Resource - private PayOrderMapper orderMapper; - - @Resource - private PayRefundMapper refundMapper; - - - @Override - public Long createApp(PayAppCreateReqVO createReqVO) { - // 插入 - PayAppDO app = PayAppConvert.INSTANCE.convert(createReqVO); - appMapper.insert(app); - // 返回 - return app.getId(); - } - - @Override - public void updateApp(PayAppUpdateReqVO updateReqVO) { - // 校验存在 - this.validateAppExists(updateReqVO.getId()); - // 更新 - PayAppDO updateObj = PayAppConvert.INSTANCE.convert(updateReqVO); - appMapper.updateById(updateObj); - } - - @Override - public void deleteApp(Long id) { - // 校验存在 - this.validateAppExists(id); - this.validateOrderTransactionExist(id); - - // 删除 - appMapper.deleteById(id); - } - - private void validateAppExists(Long id) { - if (appMapper.selectById(id) == null) { - throw exception(PAY_APP_NOT_FOUND); - } - } - - @Override - public PayAppDO getApp(Long id) { - return appMapper.selectById(id); - } - - @Override - public List getAppList(Collection ids) { - return appMapper.selectBatchIds(ids); - } - - @Override - public PageResult getAppPage(PayAppPageReqVO pageReqVO) { - Set merchantIdList = this.getMerchantCondition(pageReqVO.getMerchantName()); - if (StrUtil.isNotBlank(pageReqVO.getMerchantName()) && CollectionUtil.isEmpty(merchantIdList)) { - return new PageResult<>(); - } - return appMapper.selectPage(pageReqVO, merchantIdList); - } - - @Override - public List getAppList(PayAppExportReqVO exportReqVO) { - Set merchantIdList = this.getMerchantCondition(exportReqVO.getMerchantName()); - if (StrUtil.isNotBlank(exportReqVO.getMerchantName()) && CollectionUtil.isEmpty(merchantIdList)) { - return new ArrayList<>(); - } - return appMapper.selectList(exportReqVO, merchantIdList); - } - - /** - * 获取商户编号集合,根据商户名称模糊查询得到所有的商户编号集合 - * - * @param merchantName 商户名称 - * @return 商户编号集合 - */ - private Set getMerchantCondition(String merchantName) { - if (StrUtil.isBlank(merchantName)) { - return Collections.emptySet(); - } - return convertSet(merchantMapper.getMerchantListByName(merchantName), PayMerchantDO::getId); - } - - /** - * 修改应用信息状态 - * - * @param id 应用编号 - * @param status 状态{@link CommonStatusEnum} - */ - @Override - public void updateAppStatus(Long id, Integer status) { - // 校验商户存在 - this.checkAppExists(id); - // 更新状态 - PayAppDO app = new PayAppDO(); - app.setId(id); - app.setStatus(status); - appMapper.updateById(app); - } - - /** - * 根据商户 ID 获得支付应用信息列表, - * - * @param merchantId 商户 ID - * @return 支付应用信息列表 - */ - @Override - public List getListByMerchantId(String merchantId) { - return appMapper.getListByMerchantId(merchantId); - } - - /** - * 检查商户是否存在 - * - * @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); - } - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelService.java deleted file mode 100644 index 1eeb567..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelService.java +++ /dev/null @@ -1,107 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.channel; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.*; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import org.springframework.web.multipart.MultipartFile; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; - -/** - * 支付渠道 Service 接口 - * - * @author aquan - */ -public interface PayChannelService { - - /** - * 创建支付渠道 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createChannel(@Valid PayChannelCreateReqVO createReqVO); - - /** - * 更新支付渠道 - * - * @param updateReqVO 更新信息 - */ - void updateChannel(@Valid PayChannelUpdateReqVO updateReqVO); - - /** - * 删除支付渠道 - * - * @param id 编号 - */ - void deleteChannel(Long id); - - /** - * 获得支付渠道 - * - * @param id 编号 - * @return 支付渠道 - */ - PayChannelDO getChannel(Long id); - - /** - * 获得支付渠道 - * 列表 - * - * @param ids 编号 - * @return 支付渠道 - * 列表 - */ - List getChannelList(Collection ids); - - /** - * 获得支付渠道 - * 分页 - * - * @param pageReqVO 分页查询 - * @return 支付渠道 - * 分页 - */ - PageResult getChannelPage(PayChannelPageReqVO pageReqVO); - - /** - * 获得支付渠道 - * 列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 支付渠道列表 - */ - List getChannelList(PayChannelExportReqVO exportReqVO); - - /** - * 根据支付应用ID集合获得支付渠道列表 - * - * @param appIds 应用编号集合 - * @return 支付渠道列表 - */ - List getChannelListByAppIds(Collection appIds); - - /** - * 根据条件获取通道数量 - * - * @param merchantId 商户编号 - * @param appid 应用编号 - * @param code 通道编码 - * @return 数量 - */ - Integer getChannelCountByConditions(Long merchantId, Long appid, String code); - - /** - * 根据条件获取通道 - * - * @param merchantId 商户编号 - * @param appid 应用编号 - * @param code 通道编码 - * @return 数量 - */ - PayChannelDO getChannelByConditions(Long merchantId, Long appid, String code); - - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java deleted file mode 100644 index 6ba21f8..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/impl/PayChannelServiceImpl.java +++ /dev/null @@ -1,161 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl; - -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.json.JSONUtil; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelCreateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelUpdateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.convert.channel.PayChannelConvert; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel.PayChannelMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import javax.validation.Validator; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.CHANNEL_EXIST_SAME_CHANNEL_ERROR; -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.CHANNEL_NOT_EXISTS; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; - -/** - * 支付渠道 Service 实现类 - * - * @author aquan - */ -@Service -@Slf4j -@Validated -public class PayChannelServiceImpl implements PayChannelService { - - @Resource - private PayChannelMapper channelMapper; - - @Resource - private Validator validator; - - @Override - public Long createChannel(PayChannelCreateReqVO reqVO) { - // 断言是否有重复的 - PayChannelDO channelDO = this.getChannelByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode()); - if (ObjectUtil.isNotNull(channelDO)) { - throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR); - } - - // 新增渠道 - PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO); - settingConfigAndCheckParam(channel, reqVO.getConfig()); - channelMapper.insert(channel); - return channel.getId(); - } - - @Override - public void updateChannel(PayChannelUpdateReqVO updateReqVO) { - // 校验存在 - this.validateChannelExists(updateReqVO.getId()); - // 更新 - PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO); - settingConfigAndCheckParam(channel, updateReqVO.getConfig()); - channelMapper.updateById(channel); - } - - @Override - public void deleteChannel(Long id) { - // 校验存在 - this.validateChannelExists(id); - // 删除 - channelMapper.deleteById(id); - } - - private void validateChannelExists(Long id) { - if (channelMapper.selectById(id) == null) { - throw exception(CHANNEL_NOT_EXISTS); - } - } - - @Override - public PayChannelDO getChannel(Long id) { - return channelMapper.selectById(id); - } - - @Override - public List getChannelList(Collection ids) { - return channelMapper.selectBatchIds(ids); - } - - @Override - public PageResult getChannelPage(PayChannelPageReqVO pageReqVO) { - return channelMapper.selectPage(pageReqVO); - } - - @Override - public List getChannelList(PayChannelExportReqVO exportReqVO) { - return channelMapper.selectList(exportReqVO); - } - - /** - * 根据支付应用ID集合获得支付渠道列表 - * - * @param appIds 应用编号集合 - * @return 支付渠道列表 - */ - @Override - public List getChannelListByAppIds(Collection appIds) { - return channelMapper.getChannelListByAppIds(appIds); - } - - - /** - * 根据条件获取通道数量 - * - * @param merchantId 商户编号 - * @param appid 应用编号 - * @param code 通道编码 - * @return 数量 - */ - @Override - public Integer getChannelCountByConditions(Long merchantId, Long appid, String code) { - return this.channelMapper.selectCount(merchantId, appid, code); - } - - /** - * 根据条件获取通道 - * - * @param merchantId 商户编号 - * @param appid 应用编号 - * @param code 通道编码 - * @return 数量 - */ - @Override - public PayChannelDO getChannelByConditions(Long merchantId, Long appid, String code) { - return this.channelMapper.selectOne(merchantId, appid, code); - } - - /** - * 设置渠道配置以及参数校验 - * - * @param channel 渠道 - * @param configStr 配置 - */ - private void settingConfigAndCheckParam(PayChannelDO channel, String configStr) { - // 得到这个渠道是微信的还是支付宝的 - Class payClass = PayChannelEnum.getByCode(channel.getCode()).getConfigClass(); - if (ObjectUtil.isNull(payClass)) { - throw exception(CHANNEL_NOT_EXISTS); - } - PayClientConfig config = JSONUtil.toBean(configStr, payClass); - - // 验证参数 - config.validate(validator); - channel.setConfig(config); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java deleted file mode 100644 index b8e74dd..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantService.java +++ /dev/null @@ -1,104 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.merchant; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; - -import javax.validation.Valid; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * 支付商户信息 Service 接口 - * - * @author aquan - */ -public interface PayMerchantService { - - /** - * 创建支付商户信息 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createMerchant(@Valid PayMerchantCreateReqVO createReqVO); - - /** - * 更新支付商户信息 - * - * @param updateReqVO 更新信息 - */ - void updateMerchant(@Valid PayMerchantUpdateReqVO updateReqVO); - - /** - * 删除支付商户信息 - * - * @param id 编号 - */ - void deleteMerchant(Long id); - - /** - * 获得支付商户信息 - * - * @param id 编号 - * @return 支付商户信息 - */ - PayMerchantDO getMerchant(Long id); - - /** - * 获得支付商户信息列表 - * - * @param ids 编号 - * @return 支付商户信息列表 - */ - List getMerchantList(Collection ids); - - /** - * 获得支付商户信息分页 - * - * @param pageReqVO 分页查询 - * @return 支付商户信息分页 - */ - PageResult getMerchantPage(PayMerchantPageReqVO pageReqVO); - - /** - * 获得支付商户信息列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 支付商户信息列表 - */ - List getMerchantList(PayMerchantExportReqVO exportReqVO); - - /** - * 修改商户状态 - * - * @param id 商户编号 - * @param status 状态 - */ - void updateMerchantStatus(Long id, Integer status); - - /** - * 根据商户名称模糊查询商户集合 - * - * @param merchantName 商户名称 - * @return 商户集合 - */ - List getMerchantListByName(String merchantName); - - /** - * 获得指定编号的商户 Map - * - * @param merchantIds 商户编号数组 - * @return 商户 Map - */ - default Map getMerchantMap(Collection merchantIds) { - List list = this.getMerchantList(merchantIds); - return CollectionUtils.convertMap(list, PayMerchantDO::getId); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java deleted file mode 100644 index b80132a..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/impl/PayMerchantServiceImpl.java +++ /dev/null @@ -1,150 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.merchant.impl; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.convert.merchant.PayMerchantConvert; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app.PayAppMapper; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import com.google.common.annotations.VisibleForTesting; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_EXIST_APP_CANT_DELETE; -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; - -/** - * 支付商户信息 Service 实现类 - * - * @author aquan - */ -@Service -@Validated -public class PayMerchantServiceImpl implements PayMerchantService { - - @Resource - private PayMerchantMapper merchantMapper; - - @Resource - private PayAppMapper appMapper; - - @Override - public Long createMerchant(PayMerchantCreateReqVO createReqVO) { - // 插入 - PayMerchantDO merchant = PayMerchantConvert.INSTANCE.convert(createReqVO); - merchant.setNo(this.generateMerchantNo()); - merchantMapper.insert(merchant); - // 返回 - return merchant.getId(); - } - - @Override - public void updateMerchant(PayMerchantUpdateReqVO updateReqVO) { - // 校验存在 - this.validateMerchantExists(updateReqVO.getId()); - // 更新 - PayMerchantDO updateObj = PayMerchantConvert.INSTANCE.convert(updateReqVO); - merchantMapper.updateById(updateObj); - } - - @Override - public void deleteMerchant(Long id) { - // 校验 - this.validateMerchantExists(id); - this.validateAppExists(id); - // 删除 - merchantMapper.deleteById(id); - } - - @Override - public PayMerchantDO getMerchant(Long id) { - return merchantMapper.selectById(id); - } - - @Override - public List getMerchantList(Collection ids) { - return merchantMapper.selectBatchIds(ids); - } - - @Override - public PageResult getMerchantPage(PayMerchantPageReqVO pageReqVO) { - return merchantMapper.selectPage(pageReqVO); - } - - @Override - public List getMerchantList(PayMerchantExportReqVO exportReqVO) { - return merchantMapper.selectList(exportReqVO); - } - - @Override - public void updateMerchantStatus(Long id, Integer status) { - // 校验商户存在 - this.checkMerchantExists(id); - // 更新状态 - PayMerchantDO merchant = new PayMerchantDO(); - merchant.setId(id); - merchant.setStatus(status); - merchantMapper.updateById(merchant); - } - - @Override - public List getMerchantListByName(String merchantName) { - return this.merchantMapper.getMerchantListByName(merchantName); - } - - @VisibleForTesting - public void checkMerchantExists(Long id) { - if (id == null) { - return; - } - PayMerchantDO merchant = merchantMapper.selectById(id); - if (merchant == null) { - throw exception(PAY_MERCHANT_NOT_EXISTS); - } - } - - /** - * 校验商户是否存在 - * - * @param id 商户 ID - */ - private void validateMerchantExists(Long id) { - if (ObjectUtil.isNull(merchantMapper.selectById(id))) { - throw exception(PAY_MERCHANT_NOT_EXISTS); - } - } - - /** - * 校验商户是否还存在支付应用 - * - * @param id 商户ID - */ - private void validateAppExists(Long id) { - if (appMapper.selectCount(id) > 0) { - throw exception(PAY_MERCHANT_EXIST_APP_CANT_DELETE); - } - } - - // TODO @芋艿:后续增加下合适的算法 - /** - * 根据年月日时分秒毫秒生成商户号 - * - * @return 商户号 - */ - private String generateMerchantNo() { - return "M" + DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmssSSS"); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderExtensionService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderExtensionService.java deleted file mode 100755 index a139956..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderExtensionService.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * 支付订单 Service 接口 - * - * @author aquan - */ -public interface PayOrderExtensionService { - - /** - * 获得支付订单 - * - * @param id 编号 - * @return 支付订单 - */ - PayOrderExtensionDO getOrderExtension(Long id); - - /** - * 获得支付订单 - * 列表 - * - * @param ids 编号 - * @return 支付订单 - * 列表 - */ - List getOrderExtensionList(Collection ids); - - - /** - * 根据订单成功的 扩展订单ID 查询所有的扩展订单转 成 map 返回 - * - * @param successExtensionIdList 订单 ID 集合 - * @return 订单扩展 map 集合 - */ - default Map getOrderExtensionMap(Collection successExtensionIdList) { - List list = this.getOrderExtensionList(successExtensionIdList); - return CollectionUtils.convertMap(list, PayOrderExtensionDO::getId); - } - - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderService.java deleted file mode 100755 index ebdf7e3..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderService.java +++ /dev/null @@ -1,67 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.order; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * 支付订单 Service 接口 - * - * @author aquan - */ -public interface PayOrderService { - - /** - * 获得支付订单 - * - * @param id 编号 - * @return 支付订单 - */ - PayOrderDO getOrder(Long id); - - /** - * 获得支付订单 - * 分页 - * - * @param pageReqVO 分页查询 - * @return 支付订单 - * 分页 - */ - PageResult getOrderPage(PayOrderPageReqVO pageReqVO); - - /** - * 获得支付订单 - * 列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 支付订单 - * 列表 - */ - List getOrderList(PayOrderExportReqVO exportReqVO); - - /** - * 根据 ID 集合获取只包含商品名称的订单集合 - * - * @param idList 订单 ID 集合 - * @return 只包含商品名称的订单集合 - */ - List getOrderSubjectList(Collection idList); - - /** - * 根据订单 ID 集合获取订单商品名称Map集合 - * - * @param idList 订单 ID 集合 - * @return 订单商品 map 集合 - */ - default Map getOrderSubjectMap(Collection idList) { - List list = getOrderSubjectList(idList); - return CollectionUtils.convertMap(list, PayOrderDO::getId); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayRefundService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayRefundService.java deleted file mode 100755 index 1412bde..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayRefundService.java +++ /dev/null @@ -1,41 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.order; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - -import java.util.List; - -/** - * 退款订单 Service 接口 - * - * @author aquan - */ -public interface PayRefundService { - - /** - * 获得退款订单 - * - * @param id 编号 - * @return 退款订单 - */ - PayRefundDO getRefund(Long id); - - /** - * 获得退款订单分页 - * - * @param pageReqVO 分页查询 - * @return 退款订单分页 - */ - PageResult getRefundPage(PayRefundPageReqVO pageReqVO); - - /** - * 获得退款订单列表, 用于 Excel 导出 - * - * @param exportReqVO 查询条件 - * @return 退款订单列表 - */ - List getRefundList(PayRefundExportReqVO exportReqVO); - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderExtensionServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderExtensionServiceImpl.java deleted file mode 100755 index 1972756..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderExtensionServiceImpl.java +++ /dev/null @@ -1,35 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.order.impl; - -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderExtensionMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderExtensionService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; - -/** - * 支付订单 Service 实现类 - * - * @author aquan - */ -@Service -@Validated -public class PayOrderExtensionServiceImpl implements PayOrderExtensionService { - - @Resource - private PayOrderExtensionMapper orderExtensionMapper; - - @Override - public PayOrderExtensionDO getOrderExtension(Long id) { - return orderExtensionMapper.selectById(id); - } - - @Override - public List getOrderExtensionList(Collection ids) { - return orderExtensionMapper.selectBatchIds(ids); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderServiceImpl.java deleted file mode 100755 index dd6d0a8..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayOrderServiceImpl.java +++ /dev/null @@ -1,54 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.order.impl; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayOrderService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Collection; -import java.util.List; - -/** - * 支付订单 Service 实现类 - * - * @author aquan - */ -@Service -@Validated -public class PayOrderServiceImpl implements PayOrderService { - - @Resource - private PayOrderMapper orderMapper; - - @Override - public PayOrderDO getOrder(Long id) { - return orderMapper.selectById(id); - } - - @Override - public PageResult getOrderPage(PayOrderPageReqVO pageReqVO) { - return orderMapper.selectPage(pageReqVO); - } - - @Override - public List getOrderList(PayOrderExportReqVO exportReqVO) { - return orderMapper.selectList(exportReqVO); - } - - /** - * 根据 ID 集合获取只包含商品名称的订单集合 - * - * @param idList 订单 ID 集合 - * @return 只包含商品名称的订单集合 - */ - @Override - public List getOrderSubjectList(Collection idList) { - return orderMapper.findByIdListQueryOrderSubject(idList); - } - -} diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayRefundServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayRefundServiceImpl.java deleted file mode 100755 index 00f42eb..0000000 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/impl/PayRefundServiceImpl.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.order.impl; - -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayRefundMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.PayRefundService; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.List; - -/** - * 退款订单 Service 实现类 - * - * @author aquan - */ -@Service -@Validated -public class PayRefundServiceImpl implements PayRefundService { - - @Resource - private PayRefundMapper refundMapper; - - @Override - public PayRefundDO getRefund(Long id) { - return refundMapper.selectById(id); - } - - @Override - public PageResult getRefundPage(PayRefundPageReqVO pageReqVO) { - return refundMapper.selectPage(pageReqVO); - } - - @Override - public List getRefundList(PayRefundExportReqVO exportReqVO) { - return refundMapper.selectList(exportReqVO); - } - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbAndRedisUnitTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbAndRedisUnitTest.java deleted file mode 100644 index 2cc60cc..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbAndRedisUnitTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.iocoder.yudao.adminserver; - -import cn.iocoder.yudao.adminserver.config.RedisTestConfiguration; -import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; -import org.redisson.spring.starter.RedissonAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.jdbc.Sql; - -/** - * 依赖内存 DB + Redis 的单元测试 - * - * 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis - * - * @author 芋道源码 - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class) -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB -public class BaseDbAndRedisUnitTest { - - @Import({ - // DB 配置类 - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类 - DataSourceAutoConfiguration.class, // Spring DB 自动配置类 - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 - DruidDataSourceAutoConfigure.class, // Druid 自动配置类 - // MyBatis 配置类 - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类 - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 - // Redis 配置类 - RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer - RedisAutoConfiguration.class, // Spring Redis 自动配置类 - YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类 - RedissonAutoConfiguration.class, // Redisson 自动高配置类 - }) - public static class Application { - } - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbUnitTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbUnitTest.java deleted file mode 100644 index 5f7daed..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseDbUnitTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.adminserver; - -import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; -import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; -import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; -import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.jdbc.Sql; - -/** - * 依赖内存 DB 的单元测试 - * - * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法 - * - * @author 芋道源码 - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class) -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 -@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB -public class BaseDbUnitTest { - - @Import({ - // DB 配置类 - YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类 - DataSourceAutoConfiguration.class, // Spring DB 自动配置类 - DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 - DruidDataSourceAutoConfigure.class, // Druid 自动配置类 - // MyBatis 配置类 - YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类 - MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 - }) - public static class Application { - } - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseRedisUnitTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseRedisUnitTest.java deleted file mode 100644 index 7e650bc..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/BaseRedisUnitTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.adminserver; - -import cn.iocoder.yudao.adminserver.config.RedisTestConfiguration; -import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; -import cn.iocoder.yudao.framework.tracer.config.YudaoTracerAutoConfiguration; -import org.redisson.spring.starter.RedissonAutoConfiguration; -import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ActiveProfiles; - -/** - * 依赖内存 Redis 的单元测试 - * - * 相比 {@link BaseDbUnitTest} 来说,从内存 DB 改成了内存 Redis - * - * @author 芋道源码 - */ -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseRedisUnitTest.Application.class) -@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 -public class BaseRedisUnitTest { - - @Import({ - // Redis 配置类 - RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer - RedisAutoConfiguration.class, // Spring Redis 自动配置类 - YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类 - RedissonAutoConfiguration.class, // Redisson 自动高配置类 - }) - public static class Application { - } - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/config/RedisTestConfiguration.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/config/RedisTestConfiguration.java deleted file mode 100644 index 15a39f7..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/config/RedisTestConfiguration.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.adminserver.config; - -import com.github.fppt.jedismock.RedisServer; -import org.springframework.boot.autoconfigure.data.redis.RedisProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; - -import java.io.IOException; - -@Configuration(proxyBeanMethods = false) -@Lazy(false) // 禁止延迟加载 -@EnableConfigurationProperties(RedisProperties.class) -public class RedisTestConfiguration { - - /** - * 创建模拟的 Redis Server 服务器 - */ - @Bean - public RedisServer redisServer(RedisProperties properties) throws IOException { - RedisServer redisServer = new RedisServer(properties.getPort()); - // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。 - try { - redisServer.start(); - } catch (Exception ignore) {} - return redisServer; - } - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppServiceTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppServiceTest.java deleted file mode 100644 index 7dee064..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/app/PayAppServiceTest.java +++ /dev/null @@ -1,245 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.app; - -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.adminserver.BaseDbUnitTest; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppCreateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.app.vo.PayAppUpdateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.app.PayAppMapper; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.app.impl.PayAppServiceImpl; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_APP_NOT_FOUND; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.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 org.junit.jupiter.api.Assertions.*; - -/** - * {@link PayAppServiceImpl} 的单元测试类 - * - * @author 芋艿 - */ -@Import(PayAppServiceImpl.class) -public class PayAppServiceTest extends BaseDbUnitTest { - - @Resource - private PayAppServiceImpl appService; - - @Resource - private PayAppMapper appMapper; - - @MockBean(name = "payMerchantMapper") - private PayMerchantMapper payMerchantMapper; - - @Test - public void testCreateApp_success() { - // 准备参数 - PayAppCreateReqVO reqVO = randomPojo(PayAppCreateReqVO.class, o -> - o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); - - // 调用 - Long appId = appService.createApp(reqVO); - // 断言 - assertNotNull(appId); - // 校验记录的属性是否正确 - PayAppDO app = appMapper.selectById(appId); - assertPojoEquals(reqVO, app); - } - - @Test - public void testUpdateApp_success() { - // mock 数据 - PayAppDO dbApp = randomPojo(PayAppDO.class, o -> - o.setStatus(CommonStatusEnum.DISABLE.getStatus())); - appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据 - // 准备参数 - PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> { - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setId(dbApp.getId()); // 设置更新的 ID - }); - - // 调用 - appService.updateApp(reqVO); - // 校验是否更新正确 - PayAppDO app = appMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, app); - } - - @Test - public void testUpdateApp_notExists() { - // 准备参数 - PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> - o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); - // 调用, 并断言异常 - assertServiceException(() -> appService.updateApp(reqVO), PAY_APP_NOT_FOUND); - } - - @Test - public void testDeleteApp_success() { - // mock 数据 - PayAppDO dbApp = randomPojo(PayAppDO.class, o -> - o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); - appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbApp.getId(); - - // 调用 - appService.deleteApp(id); - // 校验数据不存在了 - assertNull(appMapper.selectById(id)); - } - - @Test - public void testDeleteApp_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND); - } - - @Test - public void testGetAppPage() { - Long merchantId = 1L; - Long mismatchMerchantId = 2L; - - // mock 数据 - 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.setMerchantId(merchantId); - o.setCreateTime(buildTime(2021,11,20)); - }); - - // mock 数据 - PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 - o.setId(merchantId); - o.setNo("M1008611"); - o.setName("灿哥的杂货铺"); - o.setShortName("灿灿子"); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setRemark("灿哥的杂货铺"); - o.setCreateTime(buildTime(2021,11,3)); - }); - - Mockito.when(payMerchantMapper.getMerchantListByName(dbMerchant.getName())) - .thenReturn(Collections.singletonList(dbMerchant)); - - appMapper.insert(dbApp); - // 测试 name 不匹配 - 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"))); - // 测试 merchantId 不匹配 - appMapper.insert(cloneIgnoreId(dbApp, o -> o.setMerchantId(mismatchMerchantId))); - // 测试 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.setMerchantName(dbMerchant.getName()); - reqVO.setBeginCreateTime(buildTime(2021,11,19)); - reqVO.setEndCreateTime(buildTime(2021,11,21)); - - // 调用 - PageResult pageResult = appService.getAppPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbApp, pageResult.getList().get(0)); - } - - @Test // TODO 请修改 null 为需要的值 - public void testGetAppList() { - Long merchantId = 1L; - Long mismatchMerchantId = 2L; - - // mock 数据 - 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.setMerchantId(merchantId); - o.setCreateTime(buildTime(2021,11,20)); - }); - - // mock 数据 - PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 - o.setId(merchantId); - o.setNo("M1008611"); - o.setName("灿哥的杂货铺"); - o.setShortName("灿灿子"); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setRemark("灿哥的杂货铺"); - o.setCreateTime(buildTime(2021,11,3)); - }); - - Mockito.when(payMerchantMapper.getMerchantListByName(dbMerchant.getName())) - .thenReturn(Collections.singletonList(dbMerchant)); - - appMapper.insert(dbApp); - // 测试 name 不匹配 - 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"))); - // 测试 merchantId 不匹配 - appMapper.insert(cloneIgnoreId(dbApp, o -> o.setMerchantId(mismatchMerchantId))); - // 测试 createTime 不匹配 - appMapper.insert(cloneIgnoreId(dbApp, o -> o.setCreateTime(buildTime(2021,12,21)))); - // 准备参数 - PayAppExportReqVO reqVO = new PayAppExportReqVO(); - reqVO.setName("灿灿姐的杂货铺"); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setRemark("敏敏姐的小卖铺"); - reqVO.setPayNotifyUrl("https://www.hc.com"); - reqVO.setRefundNotifyUrl("https://www.xm.com"); - reqVO.setMerchantName(dbMerchant.getName()); - reqVO.setBeginCreateTime(buildTime(2021,11,19)); - reqVO.setEndCreateTime(buildTime(2021,11,21)); - - // 调用 - List list = appService.getAppList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbApp, list.get(0)); - } - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java deleted file mode 100644 index bff90e6..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelConfig.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.channel; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import javax.validation.Validation; -import javax.validation.Validator; - -/** - * 用于初始化 validator Bean 对象 - * @author aquan - */ -@Configuration -public class PayChannelConfig { - - @Bean - public Validator validator(){ - return Validation.buildDefaultValidatorFactory().getValidator(); - } -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelServiceTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelServiceTest.java deleted file mode 100644 index b8d2bc9..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/channel/PayChannelServiceTest.java +++ /dev/null @@ -1,404 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.channel; - -import cn.iocoder.yudao.adminserver.BaseDbUnitTest; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelCreateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelUpdateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel.PayChannelMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl.PayChannelServiceImpl; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; -import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import com.alibaba.fastjson.JSON; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.CHANNEL_NOT_EXISTS; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.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 org.junit.jupiter.api.Assertions.*; - -/** - * {@link PayChannelServiceImpl} 的单元测试类 - * - * @author 芋艿 - */ -@Import({ - PayChannelServiceImpl.class, - PayChannelConfig.class -}) -public class PayChannelServiceTest extends BaseDbUnitTest { - - @Resource - private PayChannelServiceImpl channelService; - - @Resource - private PayChannelMapper channelMapper; - - @Test - public void testCreateWechatVersion2Channel_success() { - // 准备参数 - - WXPayClientConfig v2Config = getV2Config(); - PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { - o.setCode(PayChannelEnum.WX_PUB.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setConfig(JSON.toJSONString(v2Config)); - }); - - // 调用 - Long channelId = channelService.createChannel(reqVO); - // 断言 - assertNotNull(channelId); - // 校验记录的属性是否正确 - PayChannelDO channel = channelMapper.selectById(channelId); - assertPojoEquals(reqVO, channel, "config"); - // 关于config 对象应该拿出来重新对比 - assertPojoEquals(v2Config, channel.getConfig()); - - } - - @Test - public void testCreateWechatVersion3Channel_success() { - // 准备参数 - WXPayClientConfig v3Config = getV3Config(); - PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { - o.setCode(PayChannelEnum.WX_PUB.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setConfig(JSON.toJSONString(v3Config)); - }); - - // 调用 - Long channelId = channelService.createChannel(reqVO); - // 断言 - assertNotNull(channelId); - // 校验记录的属性是否正确 - PayChannelDO channel = channelMapper.selectById(channelId); - assertPojoEquals(reqVO, channel, "config"); - // 关于config 对象应该拿出来重新对比 - assertPojoEquals(v3Config, channel.getConfig()); - } - - @Test - public void testCreateAliPayPublicKeyChannel_success() { - // 准备参数 - - AlipayPayClientConfig payClientConfig = getPublicKeyConfig(); - PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { - o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setConfig(JSON.toJSONString(payClientConfig)); - }); - - // 调用 - Long channelId = channelService.createChannel(reqVO); - // 断言 - assertNotNull(channelId); - // 校验记录的属性是否正确 - PayChannelDO channel = channelMapper.selectById(channelId); - assertPojoEquals(reqVO, channel, "config"); - // 关于config 对象应该拿出来重新对比 - assertPojoEquals(payClientConfig, channel.getConfig()); - - } - - @Test - public void testCreateAliPayCertificateChannel_success() { - // 准备参数 - - AlipayPayClientConfig payClientConfig = getCertificateConfig(); - PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { - o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setConfig(JSON.toJSONString(payClientConfig)); - }); - - // 调用 - Long channelId = channelService.createChannel(reqVO); - // 断言 - assertNotNull(channelId); - // 校验记录的属性是否正确 - PayChannelDO channel = channelMapper.selectById(channelId); - assertPojoEquals(reqVO, channel, "config"); - // 关于config 对象应该拿出来重新对比 - assertPojoEquals(payClientConfig, channel.getConfig()); - } - - @Test - public void testUpdateChannel_success() { - // mock 数据 - AlipayPayClientConfig payClientConfig = getCertificateConfig(); - PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { - o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setConfig(payClientConfig); - }); - channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 - // 准备参数 - AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig(); - PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> { - o.setCode(dbChannel.getCode()); - o.setStatus(dbChannel.getStatus()); - o.setConfig(JSON.toJSONString(payClientPublicKeyConfig)); - o.setId(dbChannel.getId()); // 设置更新的 ID - }); - - // 调用 - channelService.updateChannel(reqVO); - // 校验是否更新正确 - PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, channel, "config"); - assertPojoEquals(payClientPublicKeyConfig, channel.getConfig()); - } - - @Test - public void testUpdateChannel_notExists() { - // 准备参数 - AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig(); - PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> { - o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setConfig(JSON.toJSONString(payClientPublicKeyConfig)); - }); - - // 调用, 并断言异常 - assertServiceException(() -> channelService.updateChannel(reqVO), CHANNEL_NOT_EXISTS); - } - - @Test - public void testDeleteChannel_success() { - // mock 数据 - AlipayPayClientConfig payClientConfig = getCertificateConfig(); - PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { - o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setConfig(payClientConfig); - }); - channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbChannel.getId(); - - // 调用 - channelService.deleteChannel(id); - // 校验数据不存在了 - assertNull(channelMapper.selectById(id)); - } - - @Test - public void testDeleteChannel_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS); - } - - @Test // TODO 请修改 null 为需要的值 - public void testGetChannelPage() { - // mock 数据 - AlipayPayClientConfig payClientConfig = getCertificateConfig(); - PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到 - o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setRemark("灿灿子的支付渠道"); - o.setFeeRate(0.03); - o.setMerchantId(1L); - o.setAppId(1L); - o.setConfig(payClientConfig); - o.setCreateTime(buildTime(2021,11,20)); - }); - channelMapper.insert(dbChannel); - // 执行拷贝的时候会出现异常,所以在插入后要重置为null 后续在写入新的 - dbChannel.setConfig(null); - // 测试 code 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setCode(PayChannelEnum.WX_PUB.getCode()); - })); - // 测试 status 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setStatus(CommonStatusEnum.DISABLE.getStatus()); - })); - // 测试 remark 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o ->{ - o.setConfig(payClientConfig); - o.setRemark("敏敏子的渠道"); - })); - // 测试 feeRate 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setFeeRate(1.23); - })); - // 测试 merchantId 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setMerchantId(2L); - })); - // 测试 appId 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setAppId(2L); - })); - // 测试 createTime 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setCreateTime(buildTime(2021, 10, 20)); - })); - // 准备参数 - PayChannelPageReqVO reqVO = new PayChannelPageReqVO(); - reqVO.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setRemark("灿灿子的支付渠道"); - reqVO.setFeeRate(0.03); - reqVO.setMerchantId(1L); - reqVO.setAppId(1L); - reqVO.setConfig(JSON.toJSONString(payClientConfig)); - reqVO.setBeginCreateTime(buildTime(2021,11,19)); - reqVO.setEndCreateTime(buildTime(2021,11,21)); - - // 调用 - PageResult pageResult = channelService.getChannelPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbChannel, pageResult.getList().get(0), "config"); - assertPojoEquals(payClientConfig, pageResult.getList().get(0).getConfig()); - - } - - @Test - public void testGetChannelList() { - // mock 数据 - AlipayPayClientConfig payClientConfig = getCertificateConfig(); - PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到 - o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setRemark("灿灿子的支付渠道"); - o.setFeeRate(0.03); - o.setMerchantId(1L); - o.setAppId(1L); - o.setConfig(payClientConfig); - o.setCreateTime(buildTime(2021,11,20)); - }); - channelMapper.insert(dbChannel); - // 执行拷贝的时候会出现异常,所以在插入后要重置为null 后续在写入新的 - dbChannel.setConfig(null); - // 测试 code 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setCode(PayChannelEnum.WX_PUB.getCode()); - })); - // 测试 status 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setStatus(CommonStatusEnum.DISABLE.getStatus()); - })); - // 测试 remark 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o ->{ - o.setConfig(payClientConfig); - o.setRemark("敏敏子的渠道"); - })); - // 测试 feeRate 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setFeeRate(1.23); - })); - // 测试 merchantId 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setMerchantId(2L); - })); - // 测试 appId 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setAppId(2L); - })); - // 测试 createTime 不匹配 - channelMapper.insert(cloneIgnoreId(dbChannel, o -> { - o.setConfig(payClientConfig); - o.setCreateTime(buildTime(2021, 10, 20)); - })); - // 准备参数 - PayChannelExportReqVO reqVO = new PayChannelExportReqVO(); - reqVO.setCode(PayChannelEnum.ALIPAY_APP.getCode()); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setRemark("灿灿子的支付渠道"); - reqVO.setFeeRate(0.03); - reqVO.setMerchantId(1L); - reqVO.setAppId(1L); - reqVO.setConfig(JSON.toJSONString(payClientConfig)); - reqVO.setBeginCreateTime(buildTime(2021,11,19)); - reqVO.setEndCreateTime(buildTime(2021,11,21)); - - // 调用 - List list = channelService.getChannelList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbChannel, list.get(0), "config"); - assertPojoEquals(payClientConfig, list.get(0).getConfig()); - } - - - public WXPayClientConfig getV2Config() { - return new WXPayClientConfig() - .setAppId("APP00001") - .setMchId("MCH00001") - .setApiVersion(WXPayClientConfig.API_VERSION_V2) - .setMchKey("dsa1d5s6a1d6sa16d1sa56d15a61das6") - .setApiV3Key("") - .setPrivateCertContent("") - .setPrivateKeyContent(""); - } - - public WXPayClientConfig getV3Config() { - return new WXPayClientConfig() - .setAppId("APP00001") - .setMchId("MCH00001") - .setApiVersion(WXPayClientConfig.API_VERSION_V3) - .setMchKey("") - .setApiV3Key("sdadasdsadadsa") - .setPrivateKeyContent("dsa445das415d15asd16ad156as") - .setPrivateCertContent("dsadasd45asd4s5a"); - - } - - public AlipayPayClientConfig getPublicKeyConfig() { - return new AlipayPayClientConfig() - .setServerUrl(AlipayPayClientConfig.SERVER_URL_PROD) - .setAppId("APP00001") - .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) - .setMode(AlipayPayClientConfig.MODE_PUBLIC_KEY) - .setPrivateKey("13131321312") - .setAlipayPublicKey("13321321321") - .setAppCertContent("") - .setAlipayPublicCertContent("") - .setRootCertContent(""); - } - - public AlipayPayClientConfig getCertificateConfig() { - return new AlipayPayClientConfig() - .setServerUrl(AlipayPayClientConfig.SERVER_URL_PROD) - .setAppId("APP00001") - .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) - .setMode(AlipayPayClientConfig.MODE_CERTIFICATE) - .setPrivateKey("") - .setAlipayPublicKey("") - .setAppCertContent("13321321321sda") - .setAlipayPublicCertContent("13321321321aqeqw") - .setRootCertContent("13321321321dsad"); - } - - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantServiceTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantServiceTest.java deleted file mode 100644 index 0e7cf13..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/merchant/PayMerchantServiceTest.java +++ /dev/null @@ -1,193 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.merchant; - -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.adminserver.BaseDbUnitTest; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantCreateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.merchant.vo.PayMerchantUpdateReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.impl.PayMerchantServiceImpl; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.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 org.junit.jupiter.api.Assertions.*; - -/** -* {@link PayMerchantServiceImpl} 的单元测试类 -* -* @author aquan -*/ -@Import(PayMerchantServiceImpl.class) -public class PayMerchantServiceTest extends BaseDbUnitTest { - - @Resource - private PayMerchantServiceImpl merchantService; - - @Resource - private PayMerchantMapper merchantMapper; - - @Test - public void testCreateMerchant_success() { - // 准备参数 - PayMerchantCreateReqVO reqVO = randomPojo(PayMerchantCreateReqVO.class,o -> - o.setStatus(RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())); - - // 调用 - Long merchantId = merchantService.createMerchant(reqVO); - // 断言 - assertNotNull(merchantId); - // 校验记录的属性是否正确 - PayMerchantDO merchant = merchantMapper.selectById(merchantId); - assertPojoEquals(reqVO, merchant); - } - - @Test - public void testUpdateMerchant_success() { - // mock 数据 - PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> - o.setStatus(CommonStatusEnum.ENABLE.getStatus())); - merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据 - // 准备参数 - PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class, o -> { - o.setId(dbMerchant.getId()); // 设置更新的 ID - o.setStatus(CommonStatusEnum.DISABLE.getStatus()); - }); - - // 调用 - merchantService.updateMerchant(reqVO); - // 校验是否更新正确 - PayMerchantDO merchant = merchantMapper.selectById(reqVO.getId()); // 获取最新的 - assertPojoEquals(reqVO, merchant); - } - - @Test - public void testUpdateMerchant_notExists() { - // 准备参数 - PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class); - - // 调用, 并断言异常 - assertServiceException(() -> merchantService.updateMerchant(reqVO), PAY_MERCHANT_NOT_EXISTS); - } - - @Test - public void testDeleteMerchant_success() { - // mock 数据 - PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, - o-> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); - merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据 - // 准备参数 - Long id = dbMerchant.getId(); - - // 调用 - merchantService.deleteMerchant(id); - // 校验数据不存在了 - assertNull(merchantMapper.selectById(id)); - } - - @Test - public void testDeleteMerchant_notExists() { - // 准备参数 - Long id = randomLongId(); - - // 调用, 并断言异常 - assertServiceException(() -> merchantService.deleteMerchant(id), PAY_MERCHANT_NOT_EXISTS); - } - - @Test - public void testGetMerchantPage() { - // mock 数据 - PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 - o.setNo("M1008611"); - o.setName("灿哥的杂货铺"); - o.setShortName("灿灿子"); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setRemark("灿哥的杂货铺"); - o.setCreateTime(buildTime(2021,11,3)); - }); - merchantMapper.insert(dbMerchant); - // 测试 no 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setNo("M200000"))); - // 测试 name 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setName("斌哥的杂货铺"))); - // 测试 shortName 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setShortName("斌斌子"))); - // 测试 status 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); - // 测试 remark 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setRemark("斌哥的杂货铺"))); - // 测试 createTime 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4)))); - // 准备参数 - PayMerchantPageReqVO reqVO = new PayMerchantPageReqVO(); - reqVO.setNo("M1008611"); - reqVO.setName("灿哥的杂货铺"); - reqVO.setShortName("灿灿子"); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setRemark("灿哥的杂货铺"); - reqVO.setBeginCreateTime(buildTime(2021,11,2)); - reqVO.setEndCreateTime(buildTime(2021,11,4)); - - // 调用 - PageResult pageResult = merchantService.getMerchantPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbMerchant, pageResult.getList().get(0)); - } - - @Test - public void testGetMerchantList() { - // mock 数据 - PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 - o.setNo("M1008611"); - o.setName("灿哥的杂货铺"); - o.setShortName("灿灿子"); - o.setStatus(CommonStatusEnum.ENABLE.getStatus()); - o.setRemark("灿哥的杂货铺"); - o.setCreateTime(buildTime(2021,11,3)); - }); - merchantMapper.insert(dbMerchant); - // 测试 no 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setNo("M200000"))); - // 测试 name 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setName("斌哥的杂货铺"))); - // 测试 shortName 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setShortName("斌斌子"))); - // 测试 status 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); - // 测试 remark 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setRemark("斌哥的杂货铺"))); - // 测试 createTime 不匹配 - merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4)))); - // 准备参数 - PayMerchantExportReqVO reqVO = new PayMerchantExportReqVO(); - reqVO.setNo("M1008611"); - reqVO.setName("灿哥的杂货铺"); - reqVO.setShortName("灿灿子"); - reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - reqVO.setRemark("灿哥的杂货铺"); - reqVO.setBeginCreateTime(buildTime(2021,11,2)); - reqVO.setEndCreateTime(buildTime(2021,11,4)); - - // 调用 - List list = merchantService.getMerchantList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbMerchant, list.get(0)); - } - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderServiceTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderServiceTest.java deleted file mode 100755 index 85b00a2..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/order/PayOrderServiceTest.java +++ /dev/null @@ -1,196 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.order; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.adminserver.BaseDbUnitTest; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.order.PayOrderPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayOrderMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.impl.PayOrderServiceImpl; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.date.DateUtils; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.Date; -import java.util.List; - -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.RandomUtils.randomPojo; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * {@link PayOrderServiceImpl} 的单元测试类 - * - * @author 芋艿 - */ -@Import(PayOrderServiceImpl.class) -public class PayOrderServiceTest extends BaseDbUnitTest { - - @Resource - private PayOrderServiceImpl orderService; - - @Resource - private PayOrderMapper orderMapper; - - public String generateNo() { - return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); - } - - @Test - public void testGetOrderPage() { - - String merchantOrderId = generateNo(); - String channelOrderId = generateNo(); - - // mock 数据 - PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到 - o.setMerchantId(1L); - o.setAppId(1L); - o.setChannelId(1L); - o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - o.setMerchantOrderId(merchantOrderId); - o.setSubject("灿灿子的炸弹猫"); - o.setBody("斌斌子送给灿灿子的炸弹猫"); - o.setNotifyUrl("https://hc.com/lbh"); - o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); - o.setAmount(10000L); - o.setChannelFeeRate(0.01); - o.setChannelFeeAmount(1L); - o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); - o.setUserIp("127.0.0.1"); - o.setCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); - o.setExpireTime(DateUtils.buildTime(2018, 1, 1, 10, 30, 0)); - o.setSuccessTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 2)); - o.setNotifyTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15)); - o.setSuccessExtensionId(1L); - o.setRefundStatus(PayRefundTypeEnum.NO.getStatus()); - o.setRefundTimes(0); - o.setRefundAmount(0L); - o.setChannelUserId("1008611"); - o.setChannelOrderNo(channelOrderId); - o.setUpdateTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15)); - }); - orderMapper.insert(dbOrder); - // 测试 merchantId 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantId(2L))); - // 测试 appId 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L))); - // 测试 channelId 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L))); - // 测试 channelCode 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); - // 测试 merchantOrderId 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(generateNo()))); - // 测试 notifyStatus 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); - // 测试 status 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus()))); - // 测试 refundStatus 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayRefundTypeEnum.ALL.getStatus()))); - // 测试 createTime 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(DateUtils.buildTime(2019, 1, 1, 10, 10, - 1)))); - // 准备参数 - PayOrderPageReqVO reqVO = new PayOrderPageReqVO(); - reqVO.setMerchantId(1L); - reqVO.setAppId(1L); - reqVO.setChannelId(1L); - reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - reqVO.setMerchantOrderId(merchantOrderId); - reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); - reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); - reqVO.setRefundStatus(PayRefundTypeEnum.NO.getStatus()); - reqVO.setBeginCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); - reqVO.setEndCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); - - // 调用 - PageResult pageResult = orderService.getOrderPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbOrder, pageResult.getList().get(0)); - // assertEquals(0, dbOrder.getUpdateTime().compareTo(pageResult.getList().get(0).getUpdateTime())); - } - - @Test - public void testGetOrderList() { - // mock 数据 - String merchantOrderId = generateNo(); - String channelOrderId = generateNo(); - PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到 - o.setMerchantId(1L); - o.setAppId(1L); - o.setChannelId(1L); - o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - o.setMerchantOrderId(merchantOrderId); - o.setSubject("灿灿子的炸弹猫"); - o.setBody("斌斌子送给灿灿子的炸弹猫"); - o.setNotifyUrl("https://hc.com/lbh"); - o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); - o.setAmount(10000L); - o.setChannelFeeRate(0.01); - o.setChannelFeeAmount(1L); - o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); - o.setUserIp("127.0.0.1"); - o.setCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); - o.setExpireTime(DateUtils.buildTime(2018, 1, 1, 10, 30, 0)); - o.setSuccessTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 2)); - o.setNotifyTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15)); - o.setSuccessExtensionId(1L); - o.setRefundStatus(PayRefundTypeEnum.NO.getStatus()); - o.setRefundTimes(0); - o.setRefundAmount(0L); - o.setChannelUserId("1008611"); - o.setChannelOrderNo(channelOrderId); - o.setUpdateTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15)); - - }); - orderMapper.insert(dbOrder); - // 测试 merchantId 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantId(2L))); - // 测试 appId 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L))); - // 测试 channelId 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L))); - // 测试 channelCode 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); - // 测试 merchantOrderId 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(generateNo()))); - // 测试 notifyStatus 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); - // 测试 status 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus()))); - // 测试 refundStatus 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayRefundTypeEnum.ALL.getStatus()))); - // 测试 createTime 不匹配 - orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(DateUtils.buildTime(2019, 1, 1, 10, 10, - 1)))); - // 准备参数 - PayOrderExportReqVO reqVO = new PayOrderExportReqVO(); - reqVO.setMerchantId(1L); - reqVO.setAppId(1L); - reqVO.setChannelId(1L); - reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - reqVO.setMerchantOrderId(merchantOrderId); - reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); - reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); - reqVO.setRefundStatus(PayRefundTypeEnum.NO.getStatus()); - reqVO.setBeginCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); - reqVO.setEndCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); - - // 调用 - List list = orderService.getOrderList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbOrder, list.get(0)); - } - -} diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java deleted file mode 100755 index ee19dba..0000000 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/pay/service/refund/PayRefundServiceTest.java +++ /dev/null @@ -1,183 +0,0 @@ -package cn.iocoder.yudao.adminserver.modules.pay.service.refund; - -import cn.iocoder.yudao.adminserver.BaseDbUnitTest; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundExportReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.controller.order.vo.refund.vo.PayRefundPageReqVO; -import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.order.PayRefundMapper; -import cn.iocoder.yudao.adminserver.modules.pay.service.order.impl.PayRefundServiceImpl; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.date.DateUtils; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import org.junit.jupiter.api.Test; -import org.springframework.context.annotation.Import; - -import javax.annotation.Resource; -import java.util.List; - -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.RandomUtils.randomPojo; -import static org.junit.jupiter.api.Assertions.assertEquals; - - -/** - * {@link PayRefundServiceImpl} 的单元测试类 - * - * @author aquan - */ -@Import(PayRefundServiceImpl.class) -public class PayRefundServiceTest extends BaseDbUnitTest { - - @Resource - private PayRefundServiceImpl refundService; - - @Resource - private PayRefundMapper refundMapper; - - - @Test - public void testGetRefundPage() { - // mock 数据 - PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到 - o.setMerchantId(1L); - o.setAppId(1L); - o.setChannelId(1L); - o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - o.setOrderId(1L); - o.setTradeNo("OT0000001"); - o.setMerchantOrderId("MOT0000001"); - o.setMerchantRefundNo("MRF0000001"); - o.setNotifyUrl("https://www.cancanzi.com"); - o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); - o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); - o.setType(PayRefundTypeEnum.SOME.getStatus()); - o.setPayAmount(100L); - o.setRefundAmount(500L); - o.setReason("就是想退款了,你有意见吗"); - o.setUserIp("127.0.0.1"); - o.setChannelOrderNo("CH0000001"); - o.setChannelRefundNo("CHR0000001"); - o.setChannelErrorCode(""); - o.setChannelErrorMsg(""); - o.setChannelExtras(""); - o.setExpireTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 30)); - o.setSuccessTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 15)); - o.setNotifyTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 20)); - o.setCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10)); - o.setUpdateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 35)); - }); - refundMapper.insert(dbRefund); - // 测试 merchantId 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantId(2L))); - // 测试 appId 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L))); - // 测试 channelCode 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); - // 测试 merchantRefundNo 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundNo("MRF1111112"))); - // 测试 notifyStatus 不匹配 - refundMapper.insert( - cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); - // 测试 status 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.CLOSE.getStatus()))); - // 测试 type 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayRefundTypeEnum.ALL.getStatus()))); - // 测试 createTime 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> - o.setCreateTime(DateUtils.buildTime(2022, 1, 1, 10, 10, 10)))); - // 准备参数 - PayRefundPageReqVO reqVO = new PayRefundPageReqVO(); - reqVO.setMerchantId(1L); - reqVO.setAppId(1L); - reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - reqVO.setMerchantRefundNo("MRF0000001"); - reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); - reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); - reqVO.setType(PayRefundTypeEnum.SOME.getStatus()); - reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10)); - reqVO.setEndCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 12)); - - - // 调用 - PageResult pageResult = refundService.getRefundPage(reqVO); - // 断言 - assertEquals(1, pageResult.getTotal()); - assertEquals(1, pageResult.getList().size()); - assertPojoEquals(dbRefund, pageResult.getList().get(0)); - } - - @Test - public void testGetRefundList() { - // mock 数据 - PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到 - o.setMerchantId(1L); - o.setAppId(1L); - o.setChannelId(1L); - o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - o.setOrderId(1L); - o.setTradeNo("OT0000001"); - o.setMerchantOrderId("MOT0000001"); - o.setMerchantRefundNo("MRF0000001"); - o.setNotifyUrl("https://www.cancanzi.com"); - o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); - o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); - o.setType(PayRefundTypeEnum.SOME.getStatus()); - o.setPayAmount(100L); - o.setRefundAmount(500L); - o.setReason("就是想退款了,你有意见吗"); - o.setUserIp("127.0.0.1"); - o.setChannelOrderNo("CH0000001"); - o.setChannelRefundNo("CHR0000001"); - o.setChannelErrorCode(""); - o.setChannelErrorMsg(""); - o.setChannelExtras(""); - o.setExpireTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 30)); - o.setSuccessTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 15)); - o.setNotifyTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 20)); - o.setCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10)); - o.setUpdateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 35)); - }); - refundMapper.insert(dbRefund); - // 测试 merchantId 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantId(2L))); - // 测试 appId 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L))); - // 测试 channelCode 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); - // 测试 merchantRefundNo 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundNo("MRF1111112"))); - // 测试 notifyStatus 不匹配 - refundMapper.insert( - cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); - // 测试 status 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.CLOSE.getStatus()))); - // 测试 type 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayRefundTypeEnum.ALL.getStatus()))); - // 测试 createTime 不匹配 - refundMapper.insert(cloneIgnoreId(dbRefund, o -> - o.setCreateTime(DateUtils.buildTime(2022, 1, 1, 10, 10, 10)))); - - // 准备参数 - PayRefundExportReqVO reqVO = new PayRefundExportReqVO(); - reqVO.setMerchantId(1L); - reqVO.setAppId(1L); - reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); - reqVO.setMerchantRefundNo("MRF0000001"); - reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); - reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); - reqVO.setType(PayRefundTypeEnum.SOME.getStatus()); - reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10)); - reqVO.setEndCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 12)); - - // 调用 - List list = refundService.getRefundList(reqVO); - // 断言 - assertEquals(1, list.size()); - assertPojoEquals(dbRefund, list.get(0)); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreConvert.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreConvert.java deleted file mode 100644 index 3e5215c..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreConvert.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.convert.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface PayOrderCoreConvert { - - PayOrderCoreConvert INSTANCE = Mappers.getMapper(PayOrderCoreConvert.class); - - PayOrderDO convert(PayOrderCreateReqDTO bean); - - PayOrderExtensionDO convert(PayOrderSubmitReqDTO bean); - - PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqDTO bean); - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayRefundCoreConvert.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayRefundCoreConvert.java deleted file mode 100644 index 4a4ada5..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayRefundCoreConvert.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.convert.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.factory.Mappers; - -@Mapper -public interface PayRefundCoreConvert { - - PayRefundCoreConvert INSTANCE = Mappers.getMapper(PayRefundCoreConvert.class); - - //TODO 太多需要处理了, 暂时不用 - @Mappings(value = { - @Mapping(source = "amount", target = "payAmount"), - @Mapping(source = "id", target = "orderId"), - @Mapping(target = "status",ignore = true) - }) - PayRefundDO convert(PayOrderDO orderDO); - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java deleted file mode 100644 index b10c090..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 提供 POJO 类的实体转换 - * - * 目前使用 MapStruct 框架 - */ -package cn.iocoder.yudao.coreservice.modules.pay.convert; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md deleted file mode 100644 index 8153487..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayAppDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayAppDO.java deleted file mode 100644 index acc849c..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayAppDO.java +++ /dev/null @@ -1,62 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 支付应用 DO - * 一个商户下,可能会有多个支付应用。例如说,京东有京东商城、京东到家等等 - * 不过一般来说,一个商户,只有一个应用哈~ - * - * 即 PayMerchantDO : PayAppDO = 1 : n - * - * @author 芋道源码 - */ -@TableName("pay_app") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayAppDO extends BaseDO { - - /** - * 应用编号,数据库自增 - */ - @TableId - private Long id; - /** - * 应用名 - */ - private String name; - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 备注 - */ - private String remark; - /** - * 支付结果的回调地址 - */ - private String payNotifyUrl; - /** - * 退款结果的回调地址 - */ - private String refundNotifyUrl; - - /** - * 商户编号 - * - * 关联 {@link PayMerchantDO#getId()} - */ - private Long merchantId; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDO.java deleted file mode 100644 index 5275dd4..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDO.java +++ /dev/null @@ -1,72 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.*; - -/** - * 支付渠道 DO - * 一个应用下,会有多种支付渠道,例如说微信支付、支付宝支付等等 - * - * 即 PayAppDO : PayChannelDO = 1 : n - * - * @author 芋道源码 - */ -@Data -@TableName(value = "pay_channel", autoResultMap = true) -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayChannelDO extends BaseDO { - - /** - * 渠道编号,数据库自增 - */ - private Long id; - /** - * 渠道编码 - * - * 枚举 {@link PayChannelEnum} - */ - private String code; - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 渠道费率,单位:百分比 - */ - private Double feeRate; - /** - * 备注 - */ - private String remark; - - /** - * 商户编号 - * - * 关联 {@link PayMerchantDO#getId()} - */ - private Long merchantId; - /** - * 应用编号 - * - * 关联 {@link PayAppDO#getId()} - */ - private Long appId; - /** - * 支付渠道配置 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private PayClientConfig config; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java deleted file mode 100644 index a0c72b9..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java +++ /dev/null @@ -1,56 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.FieldFill; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 支付商户信息 DO - * 目前暂时没有特别的用途,主要为未来多商户提供基础。 - * - * @author 芋道源码 - */ -@Data -@TableName("pay_merchant") -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayMerchantDO extends BaseDO { - - /** - * 商户编号,数据库自增 - */ - @TableId - private Long id; - /** - * 商户号 - * 例如说,M233666999 - * 只有新增时插入,不允许修改 - */ - private String no; - /** - * 商户全称 - */ - private String name; - /** - * 商户简称 - */ - private String shortName; - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - /** - * 备注 - */ - private String remark; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyLogDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyLogDO.java deleted file mode 100644 index 8562600..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyLogDO.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify; - -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * 商户支付、退款等的通知 Log - * 每次通知时,都会在该表中,记录一次 Log,方便排查问题 - * - * @author 芋道源码 - */ -@TableName("pay_notify_log") -@Data -@EqualsAndHashCode(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayNotifyLogDO extends BaseDO { - - /** - * 日志编号,自增 - */ - private Long id; - /** - * 通知任务编号 - * - * 关联 {@link PayNotifyTaskDO#getId()} - */ - private Long taskId; - /** - * 第几次被通知 - * - * 对应到 {@link PayNotifyTaskDO#getNotifyTimes()} - */ - private Integer notifyTimes; - /** - * HTTP 响应结果 - */ - private String response; - /** - * 支付通知状态 - * - * 外键 {@link PayNotifyStatusEnum} - */ - private Integer status; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyTaskDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyTaskDO.java deleted file mode 100644 index 3d10ac8..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/notify/PayNotifyTaskDO.java +++ /dev/null @@ -1,99 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.experimental.Accessors; - -import java.util.Date; - -/** - * 商户支付、退款等的通知 - * 在支付系统收到支付渠道的支付、退款的结果后,需要不断的通知到业务系统,直到成功。 - * - * @author 芋道源码 - */ -@TableName("pay_notify_task") -@Data -@EqualsAndHashCode(callSuper = true) -@Accessors(chain = true) -public class PayNotifyTaskDO extends BaseDO { - - /** - * 通知频率,单位为秒。 - * - * 算上首次的通知,实际是一共 1 + 8 = 9 次。 - */ - public static final Integer[] NOTIFY_FREQUENCY = new Integer[]{ - 15, 15, 30, 180, - 1800, 1800, 1800, 3600 - }; - - /** - * 编号,自增 - */ - private Long id; - /** - * 商户编号 - * - * 关联 {@link PayMerchantDO#getId()} - */ - private Long merchantId; - /** - * 应用编号 - * - * 关联 {@link PayAppDO#getId()} - */ - private Long appId; - /** - * 通知类型 - * - * 外键 {@link PayNotifyTypeEnum} - */ - private Integer type; - /** - * 数据编号,根据不同 type 进行关联: - * - * 1. {@link PayNotifyTypeEnum#ORDER} 时,关联 {@link PayOrderDO#getId()} - * 2. {@link PayNotifyTypeEnum#REFUND} 时,关联 {@link PayRefundDO#getId()} - */ - private Long dataId; - /** - * 商户订单编号 - */ - private String merchantOrderId; - /** - * 通知状态 - * - * 外键 {@link PayNotifyStatusEnum} - */ - private Integer status; - /** - * 下一次通知时间 - */ - private Date nextNotifyTime; - /** - * 最后一次执行时间 - */ - private Date lastExecuteTime; - /** - * 当前通知次数 - */ - private Integer notifyTimes; - /** - * 最大可通知次数 - */ - private Integer maxNotifyTimes; - /** - * 通知地址 - */ - private String notifyUrl; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java deleted file mode 100644 index 65cf94b..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java +++ /dev/null @@ -1,162 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -import java.util.Date; - -/** - * 支付订单 DO - * - * @author 芋道源码 - */ -@TableName("pay_order") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayOrderDO extends BaseDO { - - /** - * 订单编号,数据库自增 - */ - private Long id; - /** - * 商户编号 - * - * 关联 {@link PayMerchantDO#getId()} - */ - private Long merchantId; - /** - * 应用编号 - * - * 关联 {@link PayAppDO#getId()} - */ - private Long appId; - /** - * 渠道编号 - * - * 关联 {@link PayChannelDO#getId()} - */ - private Long channelId; - /** - * 渠道编码 - * - * 枚举 {@link PayChannelEnum} - */ - private String channelCode; - - // ========== 商户相关字段 ========== - - /** - * 商户订单编号 - * 例如说,内部系统 A 的订单号。需要保证每个 PayMerchantDO 唯一 - */ - private String merchantOrderId; - /** - * 商品标题 - */ - private String subject; - /** - * 商品描述信息 - */ - private String body; - /** - * 异步通知地址 - */ - private String notifyUrl; - /** - * 通知商户支付结果的回调状态 - * - * 枚举 {@link PayOrderNotifyStatusEnum} - */ - private Integer notifyStatus; -// /** -// * 商户拓展参数 -// */ -// private Map merchantExtras; - - // ========== 订单相关字段 ========== - - /** - * 支付金额,单位:分 - */ - private Long amount; - /** - * 渠道手续费,单位:百分比 - * - * 冗余 {@link PayChannelDO#getFeeRate()} - */ - private Double channelFeeRate; - /** - * 渠道手续金额,单位:分 - */ - private Long channelFeeAmount; - /** - * 支付状态 - * - * 枚举 {@link PayOrderStatusEnum} - */ - private Integer status; - /** - * 用户 IP - */ - private String userIp; - /** - * 订单失效时间 - */ - private Date expireTime; - /** - * 订单支付成功时间 - */ - private Date successTime; - /** - * 订单支付通知时间,即支付渠道的通知时间 - */ - private Date notifyTime; - /** - * 支付成功的订单拓展单编号 - * - * 关联 {@link PayOrderDO#getId()} - */ - private Long successExtensionId; - - // ========== 退款相关字段 ========== - /** - * 退款状态 - * - * 枚举 {@link PayRefundTypeEnum} - */ - private Integer refundStatus; - /** - * 退款次数 - */ - private Integer refundTimes; - /** - * 退款总金额,单位:分 - */ - private Long refundAmount; - - // ========== 渠道相关字段 ========== - /** - * 渠道用户编号 - * - * 例如说,微信 openid、支付宝账号 - */ - private String channelUserId; - /** - * 渠道订单号 - */ - private String channelOrderNo; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java deleted file mode 100644 index 5a6b843..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java +++ /dev/null @@ -1,82 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.*; - -import java.util.Map; - -/** - * 支付订单拓展 DO - * - * - * @author 芋道源码 - */ -@TableName(value = "pay_order_extension",autoResultMap = true) -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayOrderExtensionDO extends BaseDO { - - /** - * 订单拓展编号,数据库自增 - */ - private Long id; - /** - * 支付订单号,根据规则生成 - * 调用支付渠道时,使用该字段作为对接的订单号。 - * 1. 调用微信支付 https://api.mch.weixin.qq.com/pay/unifiedorder 时,使用该字段作为 out_trade_no - * 2. 调用支付宝 https://opendocs.alipay.com/apis 时,使用该字段作为 out_trade_no - * - * 例如说,P202110132239124200055 - */ - private String no; - /** - * 订单号 - * - * 关联 {@link PayOrderDO#getId()} - */ - private Long orderId; - /** - * 渠道编号 - * - * 关联 {@link PayChannelDO#getId()} - */ - private Long channelId; - /** - * 渠道编码 - */ - private String channelCode; - /** - * 用户 IP - */ - private String userIp; - /** - * 支付状态 - * - * 枚举 {@link PayOrderStatusEnum} - * 注意,只包含上述枚举的 WAITING 和 SUCCESS - */ - private Integer status; - /** - * 支付渠道的额外参数 - * - * 参见 https://www.pingxx.com/api/支付渠道%20extra%20参数说明.html - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private Map channelExtras; - /** - * 支付渠道异步通知的内容 - * - * 在支持成功后,会记录回调的数据 - */ - private String channelNotifyData; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java deleted file mode 100644 index fc897a5..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java +++ /dev/null @@ -1,196 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum; -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -import java.util.Date; - -/** - * 支付退款单 DO - * 一个支付订单,可以拥有多个支付退款单 - * - * 即 PayOrderDO : PayRefundDO = 1 : n - * - * @author 芋道源码 - */ -@TableName("pay_refund") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayRefundDO extends BaseDO { - - /** - * 退款单编号,数据库自增 - */ - @TableId - private Long id; - - /** - * 商户编号 - * - * 关联 {@link PayMerchantDO#getId()} - */ - private Long merchantId; - /** - * 应用编号 - * - * 关联 {@link PayAppDO#getId()} - */ - private Long appId; - /** - * 渠道编号 - * - * 关联 {@link PayChannelDO#getId()} - */ - private Long channelId; - /** - * 商户编码 - * - * 枚举 {@link PayChannelEnum} - */ - private String channelCode; - /** - * 订单编号 - * - * 关联 {@link PayOrderDO#getId()} - */ - private Long orderId; - - /** - * 交易订单号,根据规则生成 - * 调用支付渠道时,使用该字段作为对接的订单号。 - * 1. 调用微信支付 https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 时,使用该字段作为 out_trade_no - * 2. 调用支付宝 https://opendocs.alipay.com/apis 时,使用该字段作为 out_trade_no - * 这里对应 pay_extension 里面的 no - * 例如说,P202110132239124200055 - */ - private String tradeNo; - - - // ========== 商户相关字段 ========== - /** - * 商户订单编号 - */ - private String merchantOrderId; - - /** - * 商户退款订单号, 由商户系统产生, 由他们保证唯一,不能为空,通知商户时会传该字段。 - * 例如说,内部系统 A 的退款订单号。需要保证每个 PayMerchantDO 唯一 - * 个商户退款订单,对应一条退款请求记录。可多次提交。 渠道保持幂等 - * 使用商户退款单,作为退款请求号 - * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_9.shtml 中的 out_refund_no - * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_request_no - * 退款请求号。 - * 标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。 - * 注:针对同一次退款请求,如果调用接口失败或异常了,重试时需要保证退款请求号不能变更, - * 防止该笔交易重复退款。支付宝会保证同样的退款请求号多次请求只会退一次。 - * 退款单请求号,根据规则生成 - * 例如说,R202109181134287570000 - */ - // TODO @jason:merchantRefundNo =》merchantRefundOId - private String merchantRefundNo; - - /** - * 异步通知地址 - */ - private String notifyUrl; - - /** - * 通知商户退款结果的回调状态 - * TODO 0 未发送 1 已发送 - */ - private Integer notifyStatus; - - // ========== 退款相关字段 ========== - /** - * 退款状态 - * - * 枚举 {@link PayRefundStatusEnum} - */ - private Integer status; - - /** - * 退款类型(部分退款,全部退款) - * - * 枚举 {@link PayRefundTypeEnum} - */ - private Integer type; - /** - * 支付金额,单位:分 - */ - private Long payAmount; - /** - * 退款金额,单位:分 - */ - private Long refundAmount; - - /** - * 退款原因 - */ - private String reason; - - /** - * 用户 IP - */ - private String userIp; - - // ========== 渠道相关字段 ========== - /** - * 渠道订单号,pay_order 中的channel_order_no 对应 - */ - private String channelOrderNo; - /** - * 微信中的 refund_id - * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_9.shtml - * 支付宝没有 - * 渠道退款单号,渠道返回 - */ - private String channelRefundNo; - - /** - * 调用渠道的错误码 - */ - private String channelErrorCode; - - /** - * 调用渠道报错时,错误信息 - */ - private String channelErrorMsg; - - - /** - * 支付渠道的额外参数 - * 参见 https://www.pingxx.com/api/Refunds%20退款概述.html - */ - private String channelExtras; - - - /** - * TODO - * 退款失效时间 - */ - private Date expireTime; - /** - * 退款成功时间 - */ - private Date successTime; - /** - * 退款通知时间 - */ - private Date notifyTime; - - - - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java deleted file mode 100644 index 603ff46..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayAppCoreMapper.java +++ /dev/null @@ -1,9 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface PayAppCoreMapper extends BaseMapperX { -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayChannelCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayChannelCoreMapper.java deleted file mode 100644 index 767a16b..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayChannelCoreMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Select; - -import java.util.Date; - -@Mapper -public interface PayChannelCoreMapper extends BaseMapperX { - - default PayChannelDO selectByAppIdAndCode(Long appId, String code) { - return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code); - } - - @Select("SELECT id FROM pay_channel WHERE update_time > #{maxUpdateTime} LIMIT 1") - Long selectExistsByUpdateTimeAfter(Date maxUpdateTime); - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java deleted file mode 100644 index e3f90d6..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java +++ /dev/null @@ -1,9 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify.PayNotifyLogDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface PayNotifyLogCoreMapper extends BaseMapperX { -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java deleted file mode 100644 index 276c671..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify.PayNotifyTaskDO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -import java.util.Date; -import java.util.List; - -@Mapper -public interface PayNotifyTaskCoreMapper extends BaseMapperX { - - /** - * 获得需要通知的 PayNotifyTaskDO 记录。需要满足如下条件: - * - * 1. status 非成功 - * 2. nextNotifyTime 小于当前时间 - * - * @return PayTransactionNotifyTaskDO 数组 - */ - default List selectListByNotify() { - return selectList(new QueryWrapper() - .in("status", PayNotifyStatusEnum.WAITING.getStatus(), PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus(), - PayNotifyStatusEnum.REQUEST_FAILURE.getStatus()) - .le("next_notify_time", new Date())); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java deleted file mode 100644 index 1ed34d5..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderCoreMapper.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface PayOrderCoreMapper extends BaseMapperX { - - default PayOrderDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) { - return selectOne(new QueryWrapper().eq("app_id", appId) - .eq("merchant_order_id", merchantOrderId)); - } - - default int updateByIdAndStatus(Long id, Integer status, PayOrderDO update) { - return update(update, new QueryWrapper() - .eq("id", id).eq("status", status)); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderExtensionCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderExtensionCoreMapper.java deleted file mode 100644 index 08c95ce..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayOrderExtensionCoreMapper.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import org.apache.ibatis.annotations.Mapper; - -@Mapper -public interface PayOrderExtensionCoreMapper extends BaseMapperX { - - default PayOrderExtensionDO selectByNo(String no) { - return selectOne(PayOrderExtensionDO::getNo, no); - } - - default int updateByIdAndStatus(Long id, Integer status, PayOrderExtensionDO update) { - return update(update, new LambdaQueryWrapper() - .eq(PayOrderExtensionDO::getId, id).eq(PayOrderExtensionDO::getStatus, status)); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundCoreMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundCoreMapper.java deleted file mode 100644 index 8de1396..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/order/PayRefundCoreMapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import org.apache.ibatis.annotations.Mapper; - - -/** - * 退款订单 Mapper - * - */ -@Mapper -public interface PayRefundCoreMapper extends BaseMapperX { - - default PayRefundDO selectByReqNo(String reqNo) { - return selectOne("req_no", reqNo); - } - - default PayRefundDO selectByTradeNoAndMerchantRefundNo(String tradeNo, String merchantRefundNo){ - return selectOne("trade_no", tradeNo, "merchant_refund_no", merchantRefundNo); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/PayRedisKeyCoreConstants.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/PayRedisKeyCoreConstants.java deleted file mode 100644 index 99384ec..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/PayRedisKeyCoreConstants.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.redis; - -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; -import org.redisson.api.RLock; - -import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.HASH; - -/** - * Lock4j Redis Key 枚举类 - * - * @author 芋道源码 - */ -public interface PayRedisKeyCoreConstants { - - RedisKeyDefine PAY_NOTIFY_LOCK = new RedisKeyDefine("通知任务的分布式锁", - "pay_notify:lock:", // 参数来自 DefaultLockKeyBuilder 类 - HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构 - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/notify/PayNotifyLockCoreRedisDAO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/notify/PayNotifyLockCoreRedisDAO.java deleted file mode 100644 index 5ce6b44..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/redis/notify/PayNotifyLockCoreRedisDAO.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.dal.redis.notify; - -import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; -import org.springframework.stereotype.Repository; - -import javax.annotation.Resource; -import java.util.concurrent.TimeUnit; - -import static cn.iocoder.yudao.coreservice.modules.pay.dal.redis.PayRedisKeyCoreConstants.PAY_NOTIFY_LOCK; - -/** - * 支付通知的锁 Redis DAO - * - * @author 芋道源码 - */ -@Repository -public class PayNotifyLockCoreRedisDAO { - - @Resource - private RedissonClient redissonClient; - - public void lock(Long id, Long timeoutMillis, Runnable runnable) { - String lockKey = formatKey(id); - RLock lock = redissonClient.getLock(lockKey); - try { - lock.lock(timeoutMillis, TimeUnit.MILLISECONDS); - // 执行逻辑 - runnable.run(); - } finally { - lock.unlock(); - } - } - - private static String formatKey(Long id) { - return String.format(PAY_NOTIFY_LOCK.getKeyTemplate(), id); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java deleted file mode 100644 index f5133ad..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java +++ /dev/null @@ -1,64 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.enums; - -import cn.iocoder.yudao.framework.common.exception.ErrorCode; - -/** - * Pay 错误码 Core 枚举类 - * - * pay 系统,使用 1-007-000-000 段 - */ -public interface PayErrorCodeCoreConstants { - - /** - * ========== APP 模块 1-007-000-000 ========== - */ - 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, "支付应用存在交易中的订单,无法删除"); - - /** - * ========== CHANNEL 模块 1-007-001-000 ========== - */ - ErrorCode PAY_CHANNEL_NOT_FOUND = new ErrorCode(1007001000, "支付渠道的配置不存在"); - ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用"); - ErrorCode PAY_CHANNEL_CLIENT_NOT_FOUND = new ErrorCode(1007001002, "支付渠道的客户端不存在"); - ErrorCode CHANNEL_NOT_EXISTS = new ErrorCode(1007001003, "支付渠道不存在"); - ErrorCode CHANNEL_EXIST_SAME_CHANNEL_ERROR = new ErrorCode(1007001005, "已存在相同的渠道"); - ErrorCode CHANNEL_WECHAT_VERSION_2_MCH_KEY_IS_NULL = new ErrorCode(1007001006,"微信渠道v2版本中商户密钥不可为空"); - ErrorCode CHANNEL_WECHAT_VERSION_3_PRIVATE_KEY_IS_NULL = new ErrorCode(1007001007,"微信渠道v3版本apiclient_key.pem不可为空"); - ErrorCode CHANNEL_WECHAT_VERSION_3_CERT_KEY_IS_NULL = new ErrorCode(1007001008,"微信渠道v3版本中apiclient_cert.pem不可为空"); - ErrorCode PAY_CHANNEL_NOTIFY_VERIFY_FAILED = new ErrorCode(1007001009, "渠道通知校验失败"); - /** - * ========== ORDER 模块 1-007-002-000 ========== - */ - ErrorCode PAY_ORDER_NOT_FOUND = new ErrorCode(1007002000, "支付订单不存在"); - ErrorCode PAY_ORDER_STATUS_IS_NOT_WAITING = new ErrorCode(1007002001, "支付订单不处于待支付"); - ErrorCode PAY_ORDER_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007002002, "支付订单不处于已支付"); - ErrorCode PAY_ORDER_ERROR_USER = new ErrorCode(1007002003, "支付订单用户不正确"); - - /** - * ========== ORDER 模块(拓展单) 1-007-003-000 ========== - */ - ErrorCode PAY_ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在"); - ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, "支付交易拓展单不处于待支付"); - ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007003002, "支付订单不处于已支付"); - - // ========== 支付模块(退款) 1-007-006-000 ========== - ErrorCode PAY_REFUND_AMOUNT_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额"); - ErrorCode PAY_REFUND_ALL_REFUNDED = new ErrorCode(1007006001, "订单已经全额退款"); - ErrorCode PAY_REFUND_CHN_ORDER_NO_IS_NULL = new ErrorCode(1007006002, "该订单的渠道订单为空"); - ErrorCode PAY_REFUND_SUCCEED = new ErrorCode(1007006003, "已经退款成功"); - ErrorCode PAY_REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在"); - - - /** - * ========== 支付商户信息 1-007-004-000 ========== - */ - ErrorCode PAY_MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在"); - ErrorCode PAY_MERCHANT_EXIST_APP_CANT_DELETE = new ErrorCode(1007004001, "支付商户存在支付应用,无法删除"); - - - - - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyStatusEnum.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyStatusEnum.java deleted file mode 100644 index 2c3c6b5..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyStatusEnum.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.enums.notify; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 支付通知状态枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PayNotifyStatusEnum { - - WAITING(1, "等待通知"), - SUCCESS(2, "通知成功"), - FAILURE(3, "通知失败"), // 多次尝试,彻底失败 - REQUEST_SUCCESS(4, "请求成功,但是结果失败"), - REQUEST_FAILURE(5, "请求失败"), - - ; - - /** - * 状态 - */ - private final Integer status; - /** - * 名字 - */ - private final String name; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyTypeEnum.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyTypeEnum.java deleted file mode 100644 index a501bc5..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/notify/PayNotifyTypeEnum.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.enums.notify; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 支付通知类型 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PayNotifyTypeEnum { - - ORDER(1, "支付单"), - REFUND(2, "退款单"), - ; - - /** - * 类型 - */ - private final Integer type; - /** - * 名字 - */ - private final String name; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderNotifyStatusEnum.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderNotifyStatusEnum.java deleted file mode 100644 index 4bda485..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderNotifyStatusEnum.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.enums.order; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 支付订单的通知状态枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PayOrderNotifyStatusEnum implements IntArrayValuable { - - NO(0, "未通知"), - SUCCESS(10, "通知成功"), - FAILURE(20, "通知失败") - ; - - private final Integer status; - private final String name; - - @Override - public int[] array() { - return new int[0]; - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java deleted file mode 100644 index b61c040..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayOrderStatusEnum.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.enums.order; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 支付订单的状态枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PayOrderStatusEnum implements IntArrayValuable { - - WAITING(0, "未支付"), - SUCCESS(10, "支付成功"), - CLOSED(20, "支付关闭"), // 未付款交易超时关闭,或支付完成后全额退款 TODO 芋艿:需要优化下 - ; - - private final Integer status; - private final String name; - - @Override - public int[] array() { - return new int[0]; - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundStatusEnum.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundStatusEnum.java deleted file mode 100644 index 2a28ae9..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundStatusEnum.java +++ /dev/null @@ -1,17 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.enums.order; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public enum PayRefundStatusEnum { - - CREATE(0, "退款订单生成"), - SUCCESS(1, "退款成功"), - FAILURE(2, "退款失败"), - CLOSE(99, "退款关闭"); - - private final Integer status; - private final String name; -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundTypeEnum.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundTypeEnum.java deleted file mode 100644 index ba7ee2f..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/order/PayRefundTypeEnum.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.enums.order; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 支付订单的退款状态枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PayRefundTypeEnum implements IntArrayValuable { - - NO(0, "未退款"), - SOME(10, "部分退款"), - ALL(20, "全部退款") - ; - - private final Integer status; - private final String name; - - @Override - public int[] array() { - return new int[0]; - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java deleted file mode 100644 index 8f5ba6a..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * pay 包下,我们放支付业务,提供业务的支付能力。 - * 例如说:商户、应用、支付、退款等等 - * - * 缩写:pay - */ -package cn.iocoder.yudao.coreservice.modules.pay; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java deleted file mode 100644 index ab6f3f2..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayAppCoreService.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.merchant; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.framework.common.exception.ServiceException; - -/** - * 支付应用 Core Service 接口 - * - * @author 芋道源码 - */ -public interface PayAppCoreService { - - /** - * 支付应用的合法性 - * - * 如果不合法,抛出 {@link ServiceException} 业务异常 - * - * @param id 应用编号 - * @return 应用信息 - */ - PayAppDO validPayApp(Long id); - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayChannelCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayChannelCoreService.java deleted file mode 100644 index 76d4678..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayChannelCoreService.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.merchant; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.framework.common.exception.ServiceException; - -/** - * 支付渠道 Core Service 接口 - * - * @author 芋道源码 - */ -public interface PayChannelCoreService { - - /** - * 初始化支付客户端 - */ - void initPayClients(); - - /** - * 支付渠道的合法性 - * - * 如果不合法,抛出 {@link ServiceException} 业务异常 - * - * @param id 渠道编号 - * @return 渠道信息 - */ - PayChannelDO validPayChannel(Long id); - - /** - * 支付渠道的合法性 - * - * 如果不合法,抛出 {@link ServiceException} 业务异常 - * - * @param appId 应用编号 - * @param code 支付渠道 - * @return 渠道信息 - */ - PayChannelDO validPayChannel(Long appId, String code); - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java deleted file mode 100644 index 916b501..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.merchant.impl; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant.PayAppCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayAppCoreService; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; -import javax.validation.Valid; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; - -/** - * 支付应用 Core Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Valid -@Slf4j -public class PayAppCoreServiceImpl implements PayAppCoreService { - - @Resource - private PayAppCoreMapper payAppCoreMapper; - - @Override - public PayAppDO validPayApp(Long id) { - PayAppDO app = payAppCoreMapper.selectById(id); - // 校验是否存在 - if (app == null) { - throw exception(PAY_APP_NOT_FOUND); - } - // 校验是否禁用 - if (CommonStatusEnum.DISABLE.getStatus().equals(app.getStatus())) { - throw exception(PAY_APP_IS_DISABLE); - } - return app; - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayChannelCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayChannelCoreServiceImpl.java deleted file mode 100644 index 5029b6e..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayChannelCoreServiceImpl.java +++ /dev/null @@ -1,121 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.merchant.impl; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant.PayChannelCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants; -import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayChannelCoreService; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; -import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import javax.validation.Valid; - -import java.util.Comparator; -import java.util.Date; -import java.util.List; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; - -/** - * 支付渠道 Core Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Valid -@Slf4j -public class PayChannelCoreServiceImpl implements PayChannelCoreService { - - /** - * 定时执行 {@link #schedulePeriodicRefresh()} 的周期 - * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高 - */ - private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L; - - /** - * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新 - */ - private volatile Date maxUpdateTime; - - @Resource - private PayChannelCoreMapper payChannelCoreMapper; - - @Resource - private PayClientFactory payClientFactory; - - @Override - @PostConstruct - public void initPayClients() { - // 获取支付渠道,如果有更新 - List payChannels = this.loadPayChannelIfUpdate(maxUpdateTime); - if (CollUtil.isEmpty(payChannels)) { - return; - } - - // 创建或更新支付 Client - payChannels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), - payChannel.getCode(), payChannel.getConfig())); - - // 写入缓存 - assert payChannels.size() > 0; // 断言,避免告警 - maxUpdateTime = payChannels.stream().max(Comparator.comparing(BaseDO::getUpdateTime)).get().getUpdateTime(); - log.info("[initPayClients][初始化 PayChannel 数量为 {}]", payChannels.size()); - } - - @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD) - public void schedulePeriodicRefresh() { - initPayClients(); - } - - /** - * 如果支付渠道发生变化,从数据库中获取最新的全量支付渠道。 - * 如果未发生变化,则返回空 - * - * @param maxUpdateTime 当前支付渠道的最大更新时间 - * @return 支付渠道列表 - */ - private List loadPayChannelIfUpdate(Date maxUpdateTime) { - // 第一步,判断是否要更新。 - if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据 - log.info("[loadPayChannelIfUpdate][首次加载全量支付渠道]"); - } else { // 判断数据库中是否有更新的支付渠道 - if (payChannelCoreMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) { - return null; - } - log.info("[loadPayChannelIfUpdate][增量加载全量支付渠道]"); - } - // 第二步,如果有更新,则从数据库加载所有支付渠道 - return payChannelCoreMapper.selectList(); - } - - @Override - public PayChannelDO validPayChannel(Long id) { - PayChannelDO channel = payChannelCoreMapper.selectById(id); - this.validPayChannel(channel); - return channel; - } - - @Override - public PayChannelDO validPayChannel(Long appId, String code) { - PayChannelDO channel = payChannelCoreMapper.selectByAppIdAndCode(appId, code); - this.validPayChannel(channel); - return channel; - } - - private void validPayChannel(PayChannelDO channel) { - if (channel == null) { - throw exception(PAY_CHANNEL_NOT_FOUND); - } - if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) { - throw exception(PayErrorCodeCoreConstants.PAY_CHANNEL_IS_DISABLE); - } - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/PayNotifyCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/PayNotifyCoreService.java deleted file mode 100644 index 4683757..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/PayNotifyCoreService.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.notify; - -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; - -import javax.validation.Valid; - -/** - * 支付通知 Core Service 接口 - * - * @author 芋道源码 - */ -public interface PayNotifyCoreService { - - /** - * 创建支付通知任务 - * - * @param reqDTO 任务信息 - */ - void createPayNotifyTask(@Valid PayNotifyTaskCreateReqDTO reqDTO); - - /** - * 执行支付通知 - * - * 注意,该方法提供给定时任务调用。目前是 yudao-admin-server 进行调用 - * @return 通知数量 - */ - int executeNotify() throws InterruptedException; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java deleted file mode 100644 index 8d40ffb..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotNull; - -/** - * 支付通知创建 DTO - * - * @author 芋道源码 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayNotifyTaskCreateReqDTO { - - /** - * 类型 - */ - @NotNull(message = "类型不能为空") - private Integer type; - /** - * 数据编号 - */ - @NotNull(message = "数据编号不能为空") - private Long dataId; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/impl/PayNotifyCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/impl/PayNotifyCoreServiceImpl.java deleted file mode 100644 index dff6de7..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/impl/PayNotifyCoreServiceImpl.java +++ /dev/null @@ -1,263 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.notify.impl; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.http.HttpUtil; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify.PayNotifyLogDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.notify.PayNotifyTaskDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify.PayNotifyLogCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.notify.PayNotifyTaskCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.redis.notify.PayNotifyLockCoreRedisDAO; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.vo.PayNotifyOrderReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.vo.PayRefundOrderReqVO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayOrderCoreService; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.util.date.DateUtils; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Lazy; -import org.springframework.scheduling.annotation.Async; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import javax.validation.Valid; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import static cn.hutool.core.exceptions.ExceptionUtil.getRootCauseMessage; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.SECOND_MILLIS; -import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; - -/** - * 支付通知 Core Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Valid -@Slf4j -public class PayNotifyCoreServiceImpl implements PayNotifyCoreService { - - /** - * 通知超时时间,单位:秒 - */ - public static final int NOTIFY_TIMEOUT = 120; - /** - * {@link #NOTIFY_TIMEOUT} 的毫秒 - */ - public static final long NOTIFY_TIMEOUT_MILLIS = 120 * SECOND_MILLIS; - - @Resource - @Lazy // 循环依赖,避免报错 - private PayOrderCoreService payOrderCoreService; - - @Resource - private PayNotifyTaskCoreMapper payNotifyTaskCoreMapper; - @Resource - private PayNotifyLogCoreMapper payNotifyLogCoreMapper; - - @Resource - private ThreadPoolTaskExecutor threadPoolTaskExecutor; // TODO 芋艿:未来提供独立的线程池 - - @Resource - private PayNotifyLockCoreRedisDAO payNotifyLockCoreRedisDAO; - - @Resource - private PayRefundCoreMapper payRefundCoreMapper; - - @Resource - @Lazy // 循环依赖(自己依赖自己),避免报错 - private PayNotifyCoreServiceImpl self; - - @Override - public void createPayNotifyTask(PayNotifyTaskCreateReqDTO reqDTO) { - PayNotifyTaskDO task = new PayNotifyTaskDO(); - task.setType(reqDTO.getType()).setDataId(reqDTO.getDataId()); - task.setStatus(PayNotifyStatusEnum.WAITING.getStatus()).setNextNotifyTime(new Date()) - .setNotifyTimes(0).setMaxNotifyTimes(PayNotifyTaskDO.NOTIFY_FREQUENCY.length + 1); - // 补充 merchantId + appId + notifyUrl 字段 - if (Objects.equals(task.getType(), PayNotifyTypeEnum.ORDER.getType())) { - PayOrderDO order = payOrderCoreService.getPayOrder(task.getDataId()); // 不进行非空判断,有问题直接异常 - task.setMerchantId(order.getMerchantId()).setAppId(order.getAppId()). - setMerchantOrderId(order.getMerchantOrderId()).setNotifyUrl(order.getNotifyUrl()); - } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) { - // TODO 芋艿,需要实现下哈 - PayRefundDO refundDO = payRefundCoreMapper.selectById(task.getDataId()); - task.setMerchantId(refundDO.getMerchantId()).setAppId(refundDO.getAppId()) - .setMerchantOrderId(refundDO.getMerchantOrderId()).setNotifyUrl(refundDO.getNotifyUrl()); - } - - // 执行插入 - payNotifyTaskCoreMapper.insert(task); - - // 异步直接发起任务。虽然会有定时任务扫描,但是会导致延迟 - self.executeNotifyAsync(task); - } - - @Override - public int executeNotify() throws InterruptedException { - // 获得需要通知的任务 - List tasks = payNotifyTaskCoreMapper.selectListByNotify(); - if (CollUtil.isEmpty(tasks)) { - return 0; - } - - // 遍历,逐个通知 - CountDownLatch latch = new CountDownLatch(tasks.size()); - tasks.forEach(task -> threadPoolTaskExecutor.execute(() -> { - try { - executeNotifySync(task); - } finally { - latch.countDown(); - } - })); - // 等待完成 - this.awaitExecuteNotify(latch); - // 返回执行完成的任务数(成功 + 失败) - return tasks.size(); - } - - /** - * 等待全部支付通知的完成 - * 每 1 秒会打印一次剩余任务数量 - * - * @param latch Latch - * @throws InterruptedException 如果被打断 - */ - private void awaitExecuteNotify(CountDownLatch latch) throws InterruptedException { - long size = latch.getCount(); - for (int i = 0; i < NOTIFY_TIMEOUT; i++) { - if (latch.await(1L, TimeUnit.SECONDS)) { - return; - } - log.info("[awaitExecuteNotify][任务处理中, 总任务数({}) 剩余任务数({})]", size, latch.getCount()); - } - log.error("[awaitExecuteNotify][任务未处理完,总任务数({}) 剩余任务数({})]", size, latch.getCount()); - } - - /** - * 异步执行单个支付通知 - * - * @param task 通知任务 - */ - @Async - public void executeNotifyAsync(PayNotifyTaskDO task) { - self.executeNotifySync(task); // 使用 self,避免事务不发起 - } - - /** - * 同步执行单个支付通知 - * - * @param task 通知任务 - */ - public void executeNotifySync(PayNotifyTaskDO task) { - // 分布式锁,避免并发问题 - payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { - // 校验,当前任务是否已经被通知过 - // 虽然已经通过分布式加锁,但是可能同时满足通知的条件,然后都去获得锁。此时,第一个执行完后,第二个还是能拿到锁,然后会再执行一次。 - PayNotifyTaskDO dbTask = payNotifyTaskCoreMapper.selectById(task.getId()); - if (DateUtils.afterNow(dbTask.getNextNotifyTime())) { - log.info("[executeNotify][dbTask({}) 任务被忽略,原因是未到达下次通知时间,可能是因为并发执行了]", toJsonString(dbTask)); - return; - } - - // 执行通知 - executeNotify(dbTask); - }); - } - - @Transactional - public void executeNotify(PayNotifyTaskDO task) { - // 发起回调 - CommonResult invokeResult = null; - Throwable invokeException = null; - try { - invokeResult = executeNotifyInvoke(task); - } catch (Throwable e) { - invokeException = e; - } - - // 处理 - Integer newStatus = this.processNotifyResult(task, invokeResult, invokeException); - - // 记录 PayNotifyLog 日志 - String response = invokeException != null ? getRootCauseMessage(invokeException) : toJsonString(invokeResult); - payNotifyLogCoreMapper.insert(PayNotifyLogDO.builder().taskId(task.getId()) - .notifyTimes(task.getNotifyTimes() + 1).status(newStatus).response(response).build()); - } - - /** - * 执行单个支付任务的 HTTP 调用 - * - * @param task 通知任务 - * @return HTTP 响应 - */ - private CommonResult executeNotifyInvoke(PayNotifyTaskDO task) { - // 拼接参数 - Object request; - if (Objects.equals(task.getType(), PayNotifyTypeEnum.ORDER.getType())) { - request = PayNotifyOrderReqVO.builder().merchantOrderId(task.getMerchantOrderId()) - .payOrderId(task.getDataId()).build(); - } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) { - request = PayRefundOrderReqVO.builder().merchantOrderId(task.getMerchantOrderId()) - .payRefundId(task.getDataId()).build(); - } else { - throw new RuntimeException("未知的通知任务类型:" + toJsonString(task)); - } - // 请求地址 - String response = HttpUtil.post(task.getNotifyUrl(), toJsonString(request), - (int) NOTIFY_TIMEOUT_MILLIS); - // 解析结果 - return JsonUtils.parseObject(response, CommonResult.class); - } - - /** - * 处理并更新通知结果 - * - * @param task 通知任务 - * @param invokeResult 通知结果 - * @param invokeException 通知异常 - * @return 最终任务的状态 - */ - private Integer processNotifyResult(PayNotifyTaskDO task, CommonResult invokeResult, Throwable invokeException) { - // 设置通用的更新 PayNotifyTaskDO 的字段 - PayNotifyTaskDO updateTask = new PayNotifyTaskDO() - .setId(task.getId()) - .setLastExecuteTime(new Date()) - .setNotifyTimes(task.getNotifyTimes() + 1); - - // 情况一:调用成功 - if (invokeResult != null && invokeResult.isSuccess()) { - updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus()); - return updateTask.getStatus(); - } - // 情况二:调用失败、调用异常 - // 2.1 超过最大回调次数 - if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) { - updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus()); - return updateTask.getStatus(); - } - // 2.2 未超过最大回调次数 - updateTask.setNextNotifyTime(DateUtils.addDate(Calendar.SECOND, PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()])); - updateTask.setStatus(invokeException != null ? PayNotifyStatusEnum.REQUEST_FAILURE.getStatus() - : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus()); - return updateTask.getStatus(); - } - - private void processNotifySuccess(PayNotifyTaskDO task, PayNotifyTaskDO updateTask) { - payNotifyTaskCoreMapper.updateById(updateTask); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayNotifyOrderReqVO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayNotifyOrderReqVO.java deleted file mode 100644 index 94b1fec..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayNotifyOrderReqVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.notify.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -@ApiModel(value = "支付单的通知 Request VO", description = "业务方接入支付回调时,使用该 VO 对象") -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayNotifyOrderReqVO { - - @ApiModelProperty(value = "商户订单编号", required = true, example = "10") - @NotEmpty(message = "商户订单号不能为空") - private String merchantOrderId; - - @ApiModelProperty(value = "支付订单编号", required = true, example = "20") - @NotNull(message = "支付订单编号不能为空") - private Long payOrderId; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayRefundOrderReqVO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayRefundOrderReqVO.java deleted file mode 100644 index d436d75..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/PayRefundOrderReqVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.notify.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -@ApiModel(value = "退款单的通知 Request VO", description = "业务方接入退款回调时,使用该 VO 对象") -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayRefundOrderReqVO { - - @ApiModelProperty(value = "商户退款单编号", required = true, example = "10") - @NotEmpty(message = "商户退款单编号不能为空") - private String merchantOrderId; - - @ApiModelProperty(value = "支付退款编号", required = true, example = "20") - @NotNull(message = "支付退款编号不能为空") - private Long payRefundId; - - @ApiModelProperty(value = "退款状态(成功,失败)", required = true, example = "10") - private Integer status; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/package-info.java deleted file mode 100644 index 78667d3..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/notify/vo/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 这里的 VO 包有点特殊,是提供给接入支付模块的业务,提供回调接口时,可以直接使用 VO - * - * 例如说,支付单的回调,使用 - */ -package cn.iocoder.yudao.coreservice.modules.pay.service.notify.vo; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java deleted file mode 100644 index 07e6592..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayOrderCoreService.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order; - -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; - -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.*; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; - -import javax.validation.Valid; - -/** - * 支付订单 Core Service - * - * @author 芋道源码 - */ -public interface PayOrderCoreService { - - /** - * 获得支付单 - * - * @param id 支付单编号 - * @return 支付单 - */ - PayOrderDO getPayOrder(Long id); - - /** - * 创建支付单 - * - * @param reqDTO 创建请求 - * @return 支付单编号 - */ - Long createPayOrder(@Valid PayOrderCreateReqDTO reqDTO); - - /** - * 提交支付 - * 此时,会发起支付渠道的调用 - * - * @param reqDTO 提交请求 - * @return 提交结果 - */ - PayOrderSubmitRespDTO submitPayOrder(@Valid PayOrderSubmitReqDTO reqDTO); - - /** - * 通知支付单成功 - * - * @param channelId 渠道编号 - * @param notifyData 通知数据 - */ - void notifyPayOrder(Long channelId, PayNotifyDataDTO notifyData) throws Exception; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java deleted file mode 100644 index b56384e..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/PayRefundCoreService.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order; - -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundRespDTO; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; - -/** - * 退款单 Core Service - * - * @author jason - */ -public interface PayRefundCoreService { - - /** - * 提交退款申请 - * - * @param reqDTO 退款申请信息 - * @return 退款申请返回信息 - */ - PayRefundRespDTO submitRefundOrder(PayRefundReqDTO reqDTO); - - /** - * 渠道的退款通知 - * - * @param channelId 渠道编号 - * @param notifyData 通知数据 - * @throws Exception 退款通知异常 - */ - void notifyPayRefund(Long channelId, PayNotifyDataDTO notifyData) throws Exception; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java deleted file mode 100644 index a5d2b0f..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java +++ /dev/null @@ -1,64 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto; - -import lombok.Data; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.DecimalMin; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.io.Serializable; -import java.util.Date; - -/** - * 支付单创建 Request DTO - */ -@Data -public class PayOrderCreateReqDTO implements Serializable { - - /** - * 应用编号 - */ - @NotNull(message = "应用编号不能为空") - private Long appId; - /** - * 用户 IP - */ - @NotEmpty(message = "用户 IP 不能为空") - private String userIp; - - // ========== 商户相关字段 ========== - - /** - * 商户订单编号 - */ - @NotEmpty(message = "商户订单编号不能为空") - private String merchantOrderId; - /** - * 商品标题 - */ - @NotEmpty(message = "商品标题不能为空") - @Length(max = 32, message = "商品标题不能超过 32") - private String subject; - /** - * 商品描述 - */ - @NotEmpty(message = "商品描述信息不能为空") - @Length(max = 128, message = "商品描述信息长度不能超过128") - private String body; - - // ========== 订单相关字段 ========== - - /** - * 支付金额,单位:分 - */ - @NotNull(message = "支付金额不能为空") - @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") - private Integer amount; - - /** - * 支付过期时间 - */ - @NotNull(message = "支付过期时间不能为空") - private Date expireTime; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java deleted file mode 100644 index eb08fbb..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java +++ /dev/null @@ -1,47 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto; - -import lombok.Data; -import lombok.experimental.Accessors; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.io.Serializable; -import java.util.Map; - -/** - * 支付单提交 Request DTO - */ -@Data -@Accessors(chain = true) -public class PayOrderSubmitReqDTO implements Serializable { - - /** - * 应用编号 - */ - @NotNull(message = "应用编号不能为空") - private Long appId; - - /** - * 支付单编号 - */ - @NotNull(message = "支付单编号不能为空") - private Long id; - - /** - * 支付渠道 - */ - @NotEmpty(message = "支付渠道不能为空") - private String channelCode; - - /** - * 用户 IP - */ - @NotEmpty(message = "用户 IP 不能为空") - private String userIp; - - /** - * 支付渠道的额外参数 - */ - private Map channelExtras; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java deleted file mode 100644 index 2bcb504..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitRespDTO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto; - -import lombok.Data; - -import java.io.Serializable; - -/** - * 支付单提交 Response DTO - */ -@Data -public class PayOrderSubmitRespDTO implements Serializable { - - /** - * 支付拓展单的编号 - */ - private Long extensionId; - - /** - * 调用支付渠道的响应结果 - */ - private Object invokeResponse; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java deleted file mode 100644 index 6ec3fb1..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundReqDTO.java +++ /dev/null @@ -1,51 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -import javax.validation.constraints.DecimalMin; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; - -/** - * 退款申请单 Request DTO - */ -@Data -@Accessors(chain = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayRefundReqDTO { - - /** - * 支付订单编号 - */ - @NotNull(message = "支付订单编号不能为空") - private Long payOrderId; - - /** - * 退款金额 - */ - @NotNull(message = "退款金额不能为空") - @DecimalMin(value = "0", inclusive = false, message = "退款金额必须大于零") - private Long amount; - - /** - * 退款原因 - */ - private String reason; - - /** - * 商户退款订单号 - */ - @NotEmpty(message = "商户退款订单号不能为空") - private String merchantRefundId; - - /** - * 用户 IP - */ - private String userIp; -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java deleted file mode 100644 index d065f38..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayRefundRespDTO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -/** - * 退款申请单 Response DTO - */ -@Data -@Accessors(chain = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayRefundRespDTO { - - /** - * 支付退款单编号,自增 - */ - private Long refundId; - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java deleted file mode 100644 index 50229b1..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java +++ /dev/null @@ -1,255 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; - -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.RandomUtil; -import cn.iocoder.yudao.coreservice.modules.pay.convert.order.PayOrderCoreConvert; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderExtensionCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayAppCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayChannelCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayOrderCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitRespDTO; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.util.json.JsonUtils; -import cn.iocoder.yudao.framework.pay.config.PayProperties; -import cn.iocoder.yudao.framework.pay.core.client.PayClient; -import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderNotifyRespDTO; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.Date; -import java.util.Objects; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; - -/** - * 支付订单 Core Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -@Slf4j -public class PayOrderCoreServiceImpl implements PayOrderCoreService { - - @Resource - private PayProperties payProperties; - - @Resource - private PayAppCoreService payAppCoreService; - @Resource - private PayChannelCoreService payChannelCoreService; - @Resource - private PayNotifyCoreService payNotifyCoreService; - - @Resource - private PayClientFactory payClientFactory; - - @Resource - private PayOrderCoreMapper payOrderCoreMapper; - @Resource - private PayOrderExtensionCoreMapper payOrderExtensionCoreMapper; - - @Override - public PayOrderDO getPayOrder(Long id) { - return payOrderCoreMapper.selectById(id); - } - - @Override - public Long createPayOrder(PayOrderCreateReqDTO reqDTO) { - // 校验 App - PayAppDO app = payAppCoreService.validPayApp(reqDTO.getAppId()); - - // 查询对应的支付交易单是否已经存在。如果是,则直接返回 - PayOrderDO order = payOrderCoreMapper.selectByAppIdAndMerchantOrderId( - reqDTO.getAppId(), reqDTO.getMerchantOrderId()); - if (order != null) { - log.warn("[createPayOrder][appId({}) merchantOrderId({}) 已经存在对应的支付单({})]", order.getAppId(), - order.getMerchantOrderId(), JsonUtils.toJsonString(order)); // 理论来说,不会出现这个情况 - return app.getId(); - } - - // 创建支付交易单 - order = PayOrderCoreConvert.INSTANCE.convert(reqDTO) - .setMerchantId(app.getMerchantId()).setAppId(app.getId()); - // 商户相关字段 - order.setNotifyUrl(app.getPayNotifyUrl()) - .setNotifyStatus(PayOrderNotifyStatusEnum.NO.getStatus()); - // 订单相关字段 - order.setStatus(PayOrderStatusEnum.WAITING.getStatus()); - // 退款相关字段 - // todo @芋艿 创建支付的订单的退款状态枚举是不是有问题,应该是 PayRefundTypeEnum 吧 您这填写的是 PayOrderNotifyStatusEnum 回调状态枚举 - order.setRefundStatus(PayOrderNotifyStatusEnum.NO.getStatus()) - .setRefundTimes(0).setRefundAmount(0L); - payOrderCoreMapper.insert(order); - // 最终返回 - return order.getId(); - } - - @Override - public PayOrderSubmitRespDTO submitPayOrder(PayOrderSubmitReqDTO reqDTO) { - // 校验 App - payAppCoreService.validPayApp(reqDTO.getAppId()); - // 校验支付渠道是否有效 - PayChannelDO channel = payChannelCoreService.validPayChannel(reqDTO.getAppId(), reqDTO.getChannelCode()); - // 校验支付客户端是否正确初始化 - PayClient client = payClientFactory.getPayClient(channel.getId()); - if (client == null) { - log.error("[submitPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); - } - - // 获得 PayOrderDO ,并校验其是否存在 - PayOrderDO order = payOrderCoreMapper.selectById(reqDTO.getId()); - if (order == null || !Objects.equals(order.getAppId(), reqDTO.getAppId())) { // 是否存在 - throw exception(PAY_ORDER_NOT_FOUND); - } - if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 - throw exception(PAY_ORDER_STATUS_IS_NOT_WAITING); - } - - // 插入 PayOrderExtensionDO - PayOrderExtensionDO orderExtension = PayOrderCoreConvert.INSTANCE.convert(reqDTO) - .setOrderId(order.getId()).setNo(generateOrderExtensionNo()) - .setChannelId(channel.getId()).setChannelCode(channel.getCode()) - .setStatus(PayOrderStatusEnum.WAITING.getStatus()); - payOrderExtensionCoreMapper.insert(orderExtension); - - // 调用三方接口 - PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderCoreConvert.INSTANCE.convert2(reqDTO); - // 商户相关字段 - //TODO jason @芋艿 是否加一个属性 如tradeNo 支付订单号, 用这个merchantOrderId让人迷糊 - unifiedOrderReqDTO.setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性! - .setSubject(order.getSubject()).setBody(order.getBody()) - .setNotifyUrl(genChannelPayNotifyUrl(channel)) - .setReturnUrl(genChannelReturnUrl(channel)); - // 订单相关字段 - unifiedOrderReqDTO.setAmount(order.getAmount()).setExpireTime(order.getExpireTime()); - CommonResult unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO); - unifiedOrderResult.checkError(); - - // TODO 轮询三方接口,是否已经支付的任务 - // 返回成功 - return new PayOrderSubmitRespDTO().setExtensionId(orderExtension.getId()) - .setInvokeResponse(unifiedOrderResult.getData()); - } - - /** - * 根据支付渠道的编码,生成支付渠道的返回地址 - * @param channel 支付渠道 - * @return 支付成功返回的地址。 配置地址 + "/" + channel id - */ - private String genChannelReturnUrl(PayChannelDO channel) { - return payProperties.getPayReturnUrl() + "/" + channel.getId(); - } - - /** - * 根据支付渠道的编码,生成支付渠道的回调地址 - * - * @param channel 支付渠道 - * @return 支付渠道的回调地址 配置地址 + "/" + channel id - */ - private String genChannelPayNotifyUrl(PayChannelDO channel) { - //去掉channel code, 似乎没啥用, 用统一的回调地址 - return payProperties.getPayNotifyUrl() + "/" + channel.getId(); - } - - private String generateOrderExtensionNo() { -// wx -// 2014 -// 10 -// 27 -// 20 -// 09 -// 39 -// 5522657 -// a690389285100 - // 目前的算法 - // 时间序列,年月日时分秒 14 位 - // 纯随机,6 位 TODO 芋艿:此处估计是会有问题的,后续在调整 - return DateUtil.format(new Date(), "yyyyMMddHHmmss") + // 时间序列 - RandomUtil.randomInt(100000, 999999) // 随机。为什么是这个范围,因为偷懒 - ; - } - - @Override - @Transactional - public void notifyPayOrder(Long channelId, PayNotifyDataDTO notifyData) throws Exception { - // TODO 芋艿,记录回调日志 - log.info("[notifyPayOrder][channelId({}) 回调数据({})]", channelId, notifyData.getBody()); - - // 校验支付渠道是否有效 - PayChannelDO channel = payChannelCoreService.validPayChannel(channelId); - // 校验支付客户端是否正确初始化 - PayClient client = payClientFactory.getPayClient(channel.getId()); - if (client == null) { - log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); - } - - // 解析支付结果 - PayOrderNotifyRespDTO notifyRespDTO = client.parseOrderNotify(notifyData); - - // TODO 芋艿,先最严格的校验。即使调用方重复调用,实际哪个订单已经被重复回调的支付,也返回 false 。也没问题,因为实际已经回调成功了。 - // 1.1 查询 PayOrderExtensionDO - PayOrderExtensionDO orderExtension = payOrderExtensionCoreMapper.selectByNo( - notifyRespDTO.getOrderExtensionNo()); - if (orderExtension == null) { - throw exception(PAY_ORDER_EXTENSION_NOT_FOUND); - } - if (!PayOrderStatusEnum.WAITING.getStatus().equals(orderExtension.getStatus())) { // 校验状态,必须是待支付 - throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING); - } - // 1.2 更新 PayOrderExtensionDO - //TODO 支付宝交易超时 TRADE_FINISHED 需要更新交易关闭 - int updateCounts = payOrderExtensionCoreMapper.updateByIdAndStatus(orderExtension.getId(), - PayOrderStatusEnum.WAITING.getStatus(), PayOrderExtensionDO.builder().id(orderExtension.getId()) - .status(PayOrderStatusEnum.SUCCESS.getStatus()).channelNotifyData(notifyData.getBody()).build()); - if (updateCounts == 0) { // 校验状态,必须是待支付 - throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING); - } - log.info("[notifyPayOrder][支付拓展单({}) 更新为已支付]", orderExtension.getId()); - - // 2.1 判断 PayOrderDO 是否处于待支付 - PayOrderDO order = payOrderCoreMapper.selectById(orderExtension.getOrderId()); - if (order == null) { - throw exception(PAY_ORDER_NOT_FOUND); - } - if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 - throw exception(PAY_ORDER_STATUS_IS_NOT_WAITING); - } - // 2.2 更新 PayOrderDO - updateCounts = payOrderCoreMapper.updateByIdAndStatus(order.getId(), PayOrderStatusEnum.WAITING.getStatus(), - PayOrderDO.builder().status(PayOrderStatusEnum.SUCCESS.getStatus()).channelId(channelId).channelCode(channel.getCode()) - .successTime(notifyRespDTO.getSuccessTime()).successExtensionId(orderExtension.getId()) - .channelOrderNo(notifyRespDTO.getChannelOrderNo()).channelUserId(notifyRespDTO.getChannelUserId()) - .notifyTime(new Date()).build()); - if (updateCounts == 0) { // 校验状态,必须是待支付 - throw exception(PAY_ORDER_STATUS_IS_NOT_WAITING); - } - log.info("[notifyPayOrder][支付订单({}) 更新为已支付]", order.getId()); - - // 3. 插入支付通知记录 - payNotifyCoreService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() - .type(PayNotifyTypeEnum.ORDER.getType()).dataId(order.getId()).build()); - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java deleted file mode 100644 index 944c62a..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayRefundCoreServiceImpl.java +++ /dev/null @@ -1,235 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service.order.impl; - -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayRefundDO; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayOrderExtensionCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.order.PayRefundCoreMapper; -import cn.iocoder.yudao.coreservice.modules.pay.enums.notify.PayNotifyTypeEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderNotifyStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundStatusEnum; -import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayRefundTypeEnum; -import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayAppCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayChannelCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.PayNotifyCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundRespDTO; -import cn.iocoder.yudao.framework.pay.core.client.PayClient; -import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; -import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundNotifyDTO; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundUnifiedReqDTO; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundUnifiedRespDTO; -import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import java.util.Date; -import java.util.Objects; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; - -@Service -@Slf4j -public class PayRefundCoreServiceImpl implements PayRefundCoreService { - - @Resource - private PayOrderCoreMapper payOrderCoreMapper; - @Resource - private PayRefundCoreMapper payRefundCoreMapper; - @Resource - private PayOrderExtensionCoreMapper payOrderExtensionCoreMapper; - - @Resource - private PayAppCoreService payAppCoreService; - @Resource - private PayChannelCoreService payChannelCoreService; - @Resource - private PayNotifyCoreService payNotifyCoreService; - - @Resource - private PayClientFactory payClientFactory; - - @Override - @Transactional(rollbackFor = Exception.class) - public PayRefundRespDTO submitRefundOrder(PayRefundReqDTO req) { - // 获得 PayOrderDO - PayOrderDO order = payOrderCoreMapper.selectById(req.getPayOrderId()); - // 校验订单是否存在 - if (Objects.isNull(order) ) { - throw exception(PAY_ORDER_NOT_FOUND); - } - // 校验 App - PayAppDO app = payAppCoreService.validPayApp(order.getAppId()); - // 校验支付渠道是否有效 - PayChannelDO channel = payChannelCoreService.validPayChannel(order.getChannelId()); - // 校验支付客户端是否正确初始化 - PayClient client = payClientFactory.getPayClient(channel.getId()); - if (client == null) { - log.error("[refund][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); - } - - // 校验退款的条件 - validatePayRefund(req, order); - // 退款类型 - PayRefundTypeEnum refundType = PayRefundTypeEnum.SOME; - if (Objects.equals(req.getAmount(), order.getAmount())) { - refundType = PayRefundTypeEnum.ALL; - } - PayOrderExtensionDO orderExtensionDO = payOrderExtensionCoreMapper.selectById(order.getSuccessExtensionId()); - PayRefundDO payRefundDO = payRefundCoreMapper.selectByTradeNoAndMerchantRefundNo(orderExtensionDO.getNo(), req.getMerchantRefundId()); - if(Objects.nonNull(payRefundDO)){ - // 退款订单已经提交过。 - //TODO 校验相同退款单的金额 - // TODO @jason:咱要不封装一个 ObjectUtils.equalsAny - if (Objects.equals(PayRefundStatusEnum.SUCCESS.getStatus(), payRefundDO.getStatus()) - || Objects.equals(PayRefundStatusEnum.CLOSE.getStatus(), payRefundDO.getStatus())) { - //已成功退款 - throw exception(PAY_REFUND_SUCCEED); - } - //可以重复提交,保证 退款请求号 一致,由渠道保证幂等 - }else { - // 成功,插入退款单 状态为生成.没有和渠道交互 - // TODO @jason:搞到 convert 里。一些额外的自动,手动 set 下; - payRefundDO = PayRefundDO.builder().channelOrderNo(order.getChannelOrderNo()) - .appId(order.getAppId()) - .channelOrderNo(order.getChannelOrderNo()) - .channelCode(order.getChannelCode()) - .channelId(order.getChannelId()) - .merchantId(order.getMerchantId()) - .orderId(order.getId()) - .merchantRefundNo(req.getMerchantRefundId()) - .notifyUrl(app.getRefundNotifyUrl()) - .payAmount(order.getAmount()) - .refundAmount(req.getAmount()) - .userIp(req.getUserIp()) - .merchantOrderId(order.getMerchantOrderId()) - .tradeNo(orderExtensionDO.getNo()) - .status(PayRefundStatusEnum.CREATE.getStatus()) - .reason(req.getReason()) - .notifyStatus(PayOrderNotifyStatusEnum.NO.getStatus()) - .type(refundType.getStatus()) - .build(); - payRefundCoreMapper.insert(payRefundDO); - } - // TODO @jason:搞到 convert 里。一些额外的自动,手动 set 下; - PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO(); - unifiedReqDTO.setUserIp(req.getUserIp()) - .setAmount(req.getAmount()) - .setChannelOrderNo(order.getChannelOrderNo()) - .setPayTradeNo(orderExtensionDO.getNo()) - .setMerchantRefundId(req.getMerchantRefundId()) - .setReason(req.getReason()); - // 向渠道发起退款申请 - PayCommonResult refundUnifiedResult = client.unifiedRefund(unifiedReqDTO); - // 检查是否失败,失败抛出业务异常。 - // TODO 渠道的异常记录。 - // TODO @jason:可以先打个 warn log 哈; - refundUnifiedResult.checkError(); - // 成功在 退款回调中处理 - return PayRefundRespDTO.builder().refundId(payRefundDO.getId()).build(); - } - - - @Override - @Transactional(rollbackFor = Exception.class) - public void notifyPayRefund(Long channelId, PayNotifyDataDTO notifyData) { - log.info("[notifyPayRefund][channelId({}) 回调数据({})]", channelId, notifyData.getBody()); - // 校验支付渠道是否有效 - PayChannelDO channel = payChannelCoreService.validPayChannel(channelId); - // 校验支付客户端是否正确初始化 - PayClient client = payClientFactory.getPayClient(channel.getId()); - if (client == null) { - log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); - } - // 解析渠道退款通知数据, 统一处理 - PayRefundNotifyDTO refundNotify = client.parseRefundNotify(notifyData); - if (Objects.equals(PayNotifyRefundStatusEnum.SUCCESS,refundNotify.getStatus())){ - payRefundSuccess(refundNotify); - } else { - //TODO 支付异常, 支付宝似乎没有支付异常的通知。 - // TODO @jason:那这里可以考虑打个 error logger @芋艿 微信是否存在支付异常通知 - } - } - - private void payRefundSuccess(PayRefundNotifyDTO refundNotify) { - // 校验退款单存在 - PayRefundDO refundDO = payRefundCoreMapper.selectByTradeNoAndMerchantRefundNo(refundNotify.getTradeNo(), refundNotify.getReqNo()); - if (refundDO == null) { - log.error("[payRefundSuccess][不存在 seqNo 为{} 的支付退款单]", refundNotify.getReqNo()); - throw exception(PAY_REFUND_NOT_FOUND); - } - - // 得到已退金额 - PayOrderDO payOrderDO = payOrderCoreMapper.selectById(refundDO.getOrderId()); - Long refundedAmount = payOrderDO.getRefundAmount(); - - PayOrderStatusEnum orderStatus = PayOrderStatusEnum.SUCCESS; - if(Objects.equals(payOrderDO.getAmount(), refundedAmount+ refundDO.getRefundAmount())){ - //支付金额 = 已退金额 + 本次退款金额。 - orderStatus = PayOrderStatusEnum.CLOSED; - } - // 更新支付订单 - PayOrderDO updateOrderDO = new PayOrderDO(); - updateOrderDO.setId(refundDO.getOrderId()) - .setRefundAmount(refundedAmount + refundDO.getRefundAmount()) - .setStatus(orderStatus.getStatus()) - .setRefundTimes(payOrderDO.getRefundTimes() + 1) - .setRefundStatus(refundDO.getType()); - payOrderCoreMapper.updateById(updateOrderDO); - - // 更新退款订单 - PayRefundDO updateRefundDO = new PayRefundDO(); - updateRefundDO.setId(refundDO.getId()) - .setSuccessTime(refundNotify.getRefundSuccessTime()) - .setChannelRefundNo(refundNotify.getChannelOrderNo()) - .setTradeNo(refundNotify.getTradeNo()) - .setNotifyTime(new Date()) - .setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); - payRefundCoreMapper.updateById(updateRefundDO); - - // 插入退款通知记录 - // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调 - payNotifyCoreService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() - .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refundDO.getId()).build()); - } - - /** - * 校验是否进行退款 - * @param req 退款申请信息 - * @param order 原始支付订单信息 - */ - private void validatePayRefund(PayRefundReqDTO req, PayOrderDO order) { - // 校验状态,必须是支付状态 - if (!PayOrderStatusEnum.SUCCESS.getStatus().equals(order.getStatus())) { - throw exception(PAY_ORDER_STATUS_IS_NOT_SUCCESS); - } - // 是否已经全额退款 - if (PayRefundTypeEnum.ALL.getStatus().equals(order.getRefundStatus())) { - throw exception(PAY_REFUND_ALL_REFUNDED); - } - // 校验金额 退款金额不能大于 原定的金额 - if (req.getAmount() + order.getRefundAmount() > order.getAmount()){ - throw exception(PAY_REFUND_AMOUNT_EXCEED); - } - // 校验渠道订单号 - if (StrUtil.isEmpty(order.getChannelOrderNo())) { - throw exception(PAY_REFUND_CHN_ORDER_NO_IS_NULL); - } - //TODO 退款的期限 退款次数的控制 - } - -} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java deleted file mode 100644 index 13b4863..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.service; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/util/PaySeqUtils.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/util/PaySeqUtils.java deleted file mode 100644 index 959cef7..0000000 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/util/PaySeqUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.coreservice.modules.pay.util; - -import cn.hutool.core.date.DatePattern; -import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.RandomUtil; - -import java.util.Date; -import java.util.concurrent.atomic.AtomicLong; - -/** - * 支付相关编号的生产 - */ -public class PaySeqUtils { - - private static final AtomicLong REFUND_REQ_NO_SEQ = new AtomicLong(0L); - - private static final AtomicLong MER_REFUND_NO_SEQ = new AtomicLong(0L); - - private static final AtomicLong MER_ORDER_NO_SEQ = new AtomicLong(0L); - - /** - * 生成商户退款单号,用于测试,应该由商户系统生成 - * @return 商户退款单 - */ - public static String genMerchantRefundNo() { - return String.format("%s%s%04d", "MR", - DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN), - (int) MER_REFUND_NO_SEQ.getAndIncrement() % 10000); - } - - /** - * 生成退款请求号 - * @return 退款请求号 - */ - public static String genRefundReqNo() { - return String.format("%s%s%04d", "RR", - DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN), - (int) REFUND_REQ_NO_SEQ.getAndIncrement() % 10000); - } - - /** - * 生成商户订单编号号 用于测试,应该由商户系统生成 - * @return 商户订单编号 - */ - public static String genMerchantOrderNo() { - return String.format("%s%s%04d", "MO", - DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN), - (int) MER_ORDER_NO_SEQ.getAndIncrement() % 10000); - } -} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java index 418676f..f8a4971 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java @@ -17,10 +17,7 @@ import lombok.Getter; @AllArgsConstructor public enum PayChannelEnum { - /** - * 公众号网页 - */ - WX_PUB("wx_pub", "微信 JSAPI 支付", WXPayClientConfig.class), + WX_PUB("wx_pub", "微信 JSAPI 支付", WXPayClientConfig.class), // 公众号网页 WX_LITE("wx_lite", "微信小程序支付", WXPayClientConfig.class), WX_APP("wx_app", "微信 App 支付", WXPayClientConfig.class), @@ -34,16 +31,16 @@ public enum PayChannelEnum { *

* 参考 https://www.pingxx.com/api/支付渠道属性值.html */ - private String code; + private final String code; /** * 名字 */ - private String name; + private final String name; /** * 配置类 */ - private Class configClass; + private final Class configClass; /** * 微信支付 @@ -58,6 +55,6 @@ public enum PayChannelEnum { public static PayChannelEnum getByCode(String code) { return ArrayUtil.firstMatch(o -> o.getCode().equals(code), values()); } - + } diff --git a/yudao-module-pay/pom.xml b/yudao-module-pay/pom.xml new file mode 100644 index 0000000..36fd9ed --- /dev/null +++ b/yudao-module-pay/pom.xml @@ -0,0 +1,25 @@ + + + + cn.iocoder.boot + yudao + ${revision} + + 4.0.0 + yudao-module-pay + pom + + yudao-module-pay-api + yudao-module-pay-impl + + + ${artifactId} + + pay 模块,我们放支付业务,提供业务的支付能力。 + 例如说:商户、应用、支付、退款等等 + + + + diff --git a/yudao-module-pay/yudao-module-pay-api/pom.xml b/yudao-module-pay/yudao-module-pay-api/pom.xml new file mode 100644 index 0000000..d5ec951 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/pom.xml @@ -0,0 +1,26 @@ + + + + yudao-module-pay + cn.iocoder.boot + 1.4.0-snapshot + + 4.0.0 + yudao-module-pay-api + jar + + ${artifactId} + + pay 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-common + + + + diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java new file mode 100644 index 0000000..2f40f2d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/DictTypeConstants.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.pay.enums; + +/** + * Pay 字典类型的枚举类 + * + * @author 芋道源码 + */ +public interface DictTypeConstants { + + /** + * 支付-订单-订单状态 + */ + String PAY_ORDER_STATUS = "pay_order_status"; + + /** + * 支付-订单-订单回调商户状态 + */ + String PAY_ORDER_NOTIFY_STATUS = "pay_order_notify_status"; + + /** + * 支付-订单-订单退款状态 + */ + String PAY_ORDER_REFUND_STATUS = "pay_order_refund_status"; + + /** + * 支付-退款订单-退款状态 + */ + String PAY_REFUND_ORDER_STATUS = "pay_refund_order_status"; + + /** + * 支付-退款订单-退款类别 + */ + String PAY_REFUND_ORDER_TYPE = "pay_refund_order_type"; + +} 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 new file mode 100644 index 0000000..203cb07 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java @@ -0,0 +1,64 @@ +package cn.iocoder.yudao.module.pay.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * Pay 错误码 Core 枚举类 + * + * pay 系统,使用 1-007-000-000 段 + */ +public interface ErrorCodeConstants { + + /** + * ========== APP 模块 1-007-000-000 ========== + */ + 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, "支付应用存在交易中的订单,无法删除"); + + /** + * ========== CHANNEL 模块 1-007-001-000 ========== + */ + ErrorCode PAY_CHANNEL_NOT_FOUND = new ErrorCode(1007001000, "支付渠道的配置不存在"); + ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用"); + ErrorCode PAY_CHANNEL_CLIENT_NOT_FOUND = new ErrorCode(1007001002, "支付渠道的客户端不存在"); + ErrorCode CHANNEL_NOT_EXISTS = new ErrorCode(1007001003, "支付渠道不存在"); + ErrorCode CHANNEL_EXIST_SAME_CHANNEL_ERROR = new ErrorCode(1007001005, "已存在相同的渠道"); + ErrorCode CHANNEL_WECHAT_VERSION_2_MCH_KEY_IS_NULL = new ErrorCode(1007001006,"微信渠道v2版本中商户密钥不可为空"); + ErrorCode CHANNEL_WECHAT_VERSION_3_PRIVATE_KEY_IS_NULL = new ErrorCode(1007001007,"微信渠道v3版本apiclient_key.pem不可为空"); + ErrorCode CHANNEL_WECHAT_VERSION_3_CERT_KEY_IS_NULL = new ErrorCode(1007001008,"微信渠道v3版本中apiclient_cert.pem不可为空"); + ErrorCode PAY_CHANNEL_NOTIFY_VERIFY_FAILED = new ErrorCode(1007001009, "渠道通知校验失败"); + /** + * ========== ORDER 模块 1-007-002-000 ========== + */ + ErrorCode PAY_ORDER_NOT_FOUND = new ErrorCode(1007002000, "支付订单不存在"); + ErrorCode PAY_ORDER_STATUS_IS_NOT_WAITING = new ErrorCode(1007002001, "支付订单不处于待支付"); + ErrorCode PAY_ORDER_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007002002, "支付订单不处于已支付"); + ErrorCode PAY_ORDER_ERROR_USER = new ErrorCode(1007002003, "支付订单用户不正确"); + + /** + * ========== ORDER 模块(拓展单) 1-007-003-000 ========== + */ + ErrorCode PAY_ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在"); + ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING = new ErrorCode(1007003001, "支付交易拓展单不处于待支付"); + ErrorCode PAY_ORDER_EXTENSION_STATUS_IS_NOT_SUCCESS = new ErrorCode(1007003002, "支付订单不处于已支付"); + + // ========== 支付模块(退款) 1-007-006-000 ========== + ErrorCode PAY_REFUND_AMOUNT_EXCEED = new ErrorCode(1007006000, "退款金额超过订单可退款金额"); + ErrorCode PAY_REFUND_ALL_REFUNDED = new ErrorCode(1007006001, "订单已经全额退款"); + ErrorCode PAY_REFUND_CHN_ORDER_NO_IS_NULL = new ErrorCode(1007006002, "该订单的渠道订单为空"); + ErrorCode PAY_REFUND_SUCCEED = new ErrorCode(1007006003, "已经退款成功"); + ErrorCode PAY_REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在"); + + + /** + * ========== 支付商户信息 1-007-004-000 ========== + */ + ErrorCode PAY_MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在"); + ErrorCode PAY_MERCHANT_EXIST_APP_CANT_DELETE = new ErrorCode(1007004001, "支付商户存在支付应用,无法删除"); + + + + + +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/package-info.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/package-info.java new file mode 100644 index 0000000..756410a --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.pay; diff --git a/yudao-module-pay/yudao-module-pay-impl/pom.xml b/yudao-module-pay/yudao-module-pay-impl/pom.xml new file mode 100644 index 0000000..f8e6da5 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/pom.xml @@ -0,0 +1,103 @@ + + + + yudao-module-pay + cn.iocoder.boot + 1.4.0-snapshot + + 4.0.0 + yudao-module-pay-impl + jar + + ${artifactId} + + pay 模块,我们放支付业务,提供业务的支付能力。 + 例如说:商户、应用、支付、退款等等 + + + + + cn.iocoder.boot + yudao-module-pay-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-operatelog + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-pay + + + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + cn.iocoder.boot + yudao-spring-boot-starter-redis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-job + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mq + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + test + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + + + + + ${artifactId} + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + repackage + + + + + + + + diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java new file mode 100644 index 0000000..0d06c9e --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayAppController.java @@ -0,0 +1,163 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.*; +import cn.iocoder.yudao.module.pay.convert.app.PayAppConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.service.merchant.PayAppService; +import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService; +import cn.iocoder.yudao.module.pay.service.merchant.PayMerchantService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; + +@Slf4j +@Api(tags = "管理后台 - 支付应用信息") +@RestController +@RequestMapping("/pay/app") +@Validated +public class PayAppController { + + @Resource + private PayAppService appService; + @Resource + private PayChannelService channelService; + @Resource + private PayMerchantService merchantService; + + @PostMapping("/create") + @ApiOperation("创建支付应用信息") + @PreAuthorize("@ss.hasPermission('pay:app:create')") + public CommonResult createApp(@Valid @RequestBody PayAppCreateReqVO createReqVO) { + return success(appService.createApp(createReqVO)); + } + + @PutMapping("/update") + @ApiOperation("更新支付应用信息") + @PreAuthorize("@ss.hasPermission('pay:app:update')") + public CommonResult updateApp(@Valid @RequestBody PayAppUpdateReqVO updateReqVO) { + appService.updateApp(updateReqVO); + return success(true); + } + + @PutMapping("/update-status") + @ApiOperation("更新支付应用状态") + @PreAuthorize("@ss.hasPermission('pay:app:update')") + public CommonResult updateAppStatus(@Valid @RequestBody PayAppUpdateStatusReqVO updateReqVO) { + appService.updateAppStatus(updateReqVO.getId(), updateReqVO.getStatus()); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除支付应用信息") + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:app:delete')") + public CommonResult deleteApp(@RequestParam("id") Long id) { + appService.deleteApp(id); + return success(true); + } + + @GetMapping("/get") + @ApiOperation("获得支付应用信息") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:app:query')") + public CommonResult getApp(@RequestParam("id") Long id) { + PayAppDO app = appService.getApp(id); + return success(PayAppConvert.INSTANCE.convert(app)); + } + + @GetMapping("/list") + @ApiOperation("获得支付应用信息列表") + @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @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") + @ApiOperation("获得支付应用信息分页") + @PreAuthorize("@ss.hasPermission('pay:app:query')") + public CommonResult> getAppPage(@Valid PayAppPageReqVO pageVO) { + // 得到应用分页列表 + PageResult pageResult = appService.getAppPage(pageVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(new PageResult<>(pageResult.getTotal())); + } + + // 得到所有的应用编号,查出所有的渠道 + 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 merchantIds = CollectionUtils.convertList(pageResult.getList(), PayAppDO::getMerchantId); + Map deptMap = merchantService.getMerchantMap(merchantIds); + + // 利用反射将渠道数据复制到返回的数据结构中去 + List appList = new ArrayList<>(pageResult.getList().size()); + pageResult.getList().forEach(app -> { + // 写入应用信息的数据 + PayAppPageItemRespVO respVO = PayAppConvert.INSTANCE.pageConvert(app); + // 写入商户的数据 + respVO.setPayMerchant(PayAppConvert.INSTANCE.convert(deptMap.get(app.getMerchantId()))); + // 写入支付渠道信息的数据 + 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())); + } + + @GetMapping("/export-excel") + @ApiOperation("导出支付应用信息 Excel") + @PreAuthorize("@ss.hasPermission('pay:app:export')") + @OperateLog(type = EXPORT) + public void exportAppExcel(@Valid PayAppExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = appService.getAppList(exportReqVO); + // 导出 Excel + List datas = PayAppConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "支付应用信息.xls", "数据", PayAppExcelVO.class, datas); + } + + @GetMapping("/list-merchant-id") + @ApiOperation("根据商户 ID 查询支付应用信息") + @ApiImplicitParam(name = "merchantId", value = "商户ID", required = true, example = "1", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:merchant:query')") + public CommonResult> getMerchantListByName(@RequestParam String merchantId) { + List appListDO = appService.getListByMerchantId(merchantId); + return success(PayAppConvert.INSTANCE.convertList(appListDO)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java new file mode 100644 index 0000000..82d3a35 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayChannelController.java @@ -0,0 +1,124 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant; + +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.*; +import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; + +@Api(tags = "管理后台 - 支付渠道") +@RestController +@RequestMapping("/pay/channel") +@Validated +public class PayChannelController { + + @Resource + private PayChannelService channelService; + + @PostMapping("/create") + @ApiOperation("创建支付渠道 ") + @PreAuthorize("@ss.hasPermission('pay:channel:create')") + public CommonResult createChannel(@Valid @RequestBody PayChannelCreateReqVO createReqVO) { + return success(channelService.createChannel(createReqVO)); + } + + @PutMapping("/update") + @ApiOperation("更新支付渠道 ") + @PreAuthorize("@ss.hasPermission('pay:channel:update')") + public CommonResult updateChannel(@Valid @RequestBody PayChannelUpdateReqVO updateReqVO) { + channelService.updateChannel(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除支付渠道 ") + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:channel:delete')") + public CommonResult deleteChannel(@RequestParam("id") Long id) { + channelService.deleteChannel(id); + return success(true); + } + + @GetMapping("/get") + @ApiOperation("获得支付渠道 ") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:channel:query')") + public CommonResult getChannel(@RequestParam("id") Long id) { + PayChannelDO channel = channelService.getChannel(id); + return success(PayChannelConvert.INSTANCE.convert(channel)); + } + + @GetMapping("/list") + @ApiOperation("获得支付渠道列表") + @ApiImplicitParam(name = "ids", value = "编号列表", + required = true, example = "1024,2048", dataTypeClass = List.class) + @PreAuthorize("@ss.hasPermission('pay:channel:query')") + public CommonResult> getChannelList(@RequestParam("ids") Collection ids) { + List list = channelService.getChannelList(ids); + return success(PayChannelConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @ApiOperation("获得支付渠道分页") + @PreAuthorize("@ss.hasPermission('pay:channel:query')") + public CommonResult> getChannelPage(@Valid PayChannelPageReqVO pageVO) { + PageResult pageResult = channelService.getChannelPage(pageVO); + return success(PayChannelConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @ApiOperation("导出支付渠道Excel") + @PreAuthorize("@ss.hasPermission('pay:channel:export')") + @OperateLog(type = EXPORT) + public void exportChannelExcel(@Valid PayChannelExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = channelService.getChannelList(exportReqVO); + // 导出 Excel + List datas = PayChannelConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "支付渠道.xls", "数据", PayChannelExcelVO.class, datas); + } + + @GetMapping("/get-channel") + @ApiOperation("根据条件查询微信支付渠道") + @ApiImplicitParams({ + @ApiImplicitParam(name = "merchantId", value = "商户编号", + required = true, example = "1", dataTypeClass = Long.class), + @ApiImplicitParam(name = "appId", value = "应用编号", + required = true, example = "1", dataTypeClass = Long.class), + @ApiImplicitParam(name = "code", value = "支付渠道编码", + required = true, example = "wx_pub", dataTypeClass = String.class) + }) + @PreAuthorize("@ss.hasPermission('pay:channel:query')") + public CommonResult getChannel( + @RequestParam Long merchantId, @RequestParam Long appId, @RequestParam String code) { + // 獲取渠道 + PayChannelDO channel = channelService.getChannelByConditions(merchantId, appId, code); + if (channel == null) { + return success(new PayChannelRespVO()); + } + // 拼凑数据 + PayChannelRespVO respVo = PayChannelConvert.INSTANCE.convert(channel); + return success(respVo); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java new file mode 100644 index 0000000..0882502 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/PayMerchantController.java @@ -0,0 +1,116 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant; + +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.*; +import cn.iocoder.yudao.module.pay.convert.merchant.PayMerchantConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.service.merchant.PayMerchantService; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; + +@Api(tags = "支付商户信息") +@RestController +@RequestMapping("/pay/merchant") +@Validated +public class PayMerchantController { + + @Resource + private PayMerchantService merchantService; + + @PostMapping("/create") + @ApiOperation("创建支付商户信息") + @PreAuthorize("@ss.hasPermission('pay:merchant:create')") + public CommonResult createMerchant(@Valid @RequestBody PayMerchantCreateReqVO createReqVO) { + return success(merchantService.createMerchant(createReqVO)); + } + + @PutMapping("/update") + @ApiOperation("更新支付商户信息") + @PreAuthorize("@ss.hasPermission('pay:merchant:update')") + public CommonResult updateMerchant(@Valid @RequestBody PayMerchantUpdateReqVO updateReqVO) { + merchantService.updateMerchant(updateReqVO); + return success(true); + } + + @PutMapping("/update-status") + @ApiOperation("修改支付商户状态") + @PreAuthorize("@ss.hasPermission('pay:merchant:update')") + public CommonResult updateMerchantStatus(@Valid @RequestBody PayMerchantUpdateStatusReqVO reqVO) { + merchantService.updateMerchantStatus(reqVO.getId(), reqVO.getStatus()); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除支付商户信息") + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:merchant:delete')") + public CommonResult deleteMerchant(@RequestParam("id") Long id) { + merchantService.deleteMerchant(id); + return success(true); + } + + @GetMapping("/get") + @ApiOperation("获得支付商户信息") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:merchant:query')") + public CommonResult getMerchant(@RequestParam("id") Long id) { + PayMerchantDO merchant = merchantService.getMerchant(id); + return success(PayMerchantConvert.INSTANCE.convert(merchant)); + } + + @GetMapping("/list-by-name") + @ApiOperation("根据商户名称获得支付商户信息列表") + @ApiImplicitParam(name = "name", value = "商户名称", example = "芋道", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:merchant:query')") + public CommonResult> getMerchantListByName(@RequestParam(required = false) String name) { + List merchantListDO = merchantService.getMerchantListByName(name); + return success(PayMerchantConvert.INSTANCE.convertList(merchantListDO)); + } + + @GetMapping("/list") + @ApiOperation("获得支付商户信息列表") + @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class) + @PreAuthorize("@ss.hasPermission('pay:merchant:query')") + public CommonResult> getMerchantList(@RequestParam("ids") Collection ids) { + List list = merchantService.getMerchantList(ids); + return success(PayMerchantConvert.INSTANCE.convertList(list)); + } + + @GetMapping("/page") + @ApiOperation("获得支付商户信息分页") + @PreAuthorize("@ss.hasPermission('pay:merchant:query')") + public CommonResult> getMerchantPage(@Valid PayMerchantPageReqVO pageVO) { + PageResult pageResult = merchantService.getMerchantPage(pageVO); + return success(PayMerchantConvert.INSTANCE.convertPage(pageResult)); + } + + @GetMapping("/export-excel") + @ApiOperation("导出支付商户信息 Excel") + @PreAuthorize("@ss.hasPermission('pay:merchant:export')") + @OperateLog(type = EXPORT) + public void exportMerchantExcel(@Valid PayMerchantExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + List list = merchantService.getMerchantList(exportReqVO); + // 导出 Excel + List datas = PayMerchantConvert.INSTANCE.convertList02(list); + ExcelUtils.write(response, "支付商户信息.xls", "数据", PayMerchantExcelVO.class, datas); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java new file mode 100644 index 0000000..795b3c6 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppBaseVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import lombok.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +/** +* 支付应用信息 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class PayAppBaseVO { + + @ApiModelProperty(value = "应用名", required = true) + @NotNull(message = "应用名不能为空") + private String name; + + @ApiModelProperty(value = "开启状态", required = true) + @NotNull(message = "开启状态不能为空") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "支付结果的回调地址", required = true) + @NotNull(message = "支付结果的回调地址不能为空") + private String payNotifyUrl; + + @ApiModelProperty(value = "退款结果的回调地址", required = true) + @NotNull(message = "退款结果的回调地址不能为空") + private String refundNotifyUrl; + + @ApiModelProperty(value = "商户编号", required = true) + @NotNull(message = "商户编号不能为空") + private Long merchantId; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java new file mode 100644 index 0000000..a66a719 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppCreateReqVO.java @@ -0,0 +1,12 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import lombok.*; +import io.swagger.annotations.*; + +@ApiModel("管理后台 - 支付应用信息创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayAppCreateReqVO extends PayAppBaseVO { + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExcelVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExcelVO.java new file mode 100644 index 0000000..3fc274a --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExcelVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 支付应用信息 Excel VO + * + * @author 芋艿 + */ +@Data +public class PayAppExcelVO { + + @ExcelProperty("应用编号") + private Long id; + + @ExcelProperty("应用名") + private String name; + + @ExcelProperty("开启状态") + private Integer status; + + @ExcelProperty("备注") + private String remark; + + @ExcelProperty("支付结果的回调地址") + private String payNotifyUrl; + + @ExcelProperty("退款结果的回调地址") + private String refundNotifyUrl; + + @ExcelProperty("商户编号") + private Long merchantId; + + @ExcelProperty("创建时间") + private Date createTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java new file mode 100644 index 0000000..d8b4642 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppExportReqVO.java @@ -0,0 +1,41 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel(value = "管理后台 - 支付应用信息 Excel 导出 Request VO", description = "参数和 PayAppPageReqVO 是一致的") +@Data +public class PayAppExportReqVO { + + @ApiModelProperty(value = "应用名") + private String name; + + @ApiModelProperty(value = "开启状态") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "支付结果的回调地址") + private String payNotifyUrl; + + @ApiModelProperty(value = "退款结果的回调地址") + private String refundNotifyUrl; + + @ApiModelProperty(value = "商户名称") + private String merchantName; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java new file mode 100644 index 0000000..e5ad082 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageItemRespVO.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; +import java.util.Set; + +@ApiModel(value = "管理后台 - 支付应用信息分页查询 Response VO", description = "相比于支付信息,还会多出应用渠道的开关信息") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayAppPageItemRespVO extends PayAppBaseVO { + + @ApiModelProperty(value = "应用编号", required = true) + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + + /** + * 所属商户 + */ + private PayMerchant payMerchant; + + @ApiModel("商户") + @Data + public static class PayMerchant { + + @ApiModelProperty(value = "商户编号", required = true, example = "1") + private Long id; + + @ApiModelProperty(value = "商户名称", required = true, example = "研发部") + private String name; + + } + + @ApiModelProperty(value = "渠道编码集合", required = true, example = "alipay_pc,alipay_wap...") + private Set channelCodes; + + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java new file mode 100644 index 0000000..62af7e1 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppPageReqVO.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("管理后台 - 支付应用信息分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayAppPageReqVO extends PageParam { + + @ApiModelProperty(value = "应用名") + private String name; + + @ApiModelProperty(value = "开启状态") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "支付结果的回调地址") + private String payNotifyUrl; + + @ApiModelProperty(value = "退款结果的回调地址") + private String refundNotifyUrl; + + @ApiModelProperty(value = "商户名称") + private String merchantName; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java new file mode 100644 index 0000000..e0ac450 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppRespVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; + +@ApiModel("管理后台 - 支付应用信息 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayAppRespVO extends PayAppBaseVO { + + @ApiModelProperty(value = "应用编号", required = true) + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java new file mode 100644 index 0000000..9bdd042 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateReqVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import lombok.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +@ApiModel("管理后台 - 支付应用信息更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayAppUpdateReqVO extends PayAppBaseVO { + + @ApiModelProperty(value = "应用编号", required = true) + @NotNull(message = "应用编号不能为空") + private Long id; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java new file mode 100644 index 0000000..2ccce68 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/app/PayAppUpdateStatusReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@ApiModel("管理后台 - 应用更新状态 Request VO") +@Data +public class PayAppUpdateStatusReqVO { + + @ApiModelProperty(value = "商户编号", required = true, example = "1024") + @NotNull(message = "商户编号不能为空") + private Long id; + + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举") + @NotNull(message = "状态不能为空") + private Integer status; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java new file mode 100644 index 0000000..8b9f534 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelBaseVO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; + +import lombok.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +/** +* 支付渠道 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class PayChannelBaseVO { + + @ApiModelProperty(value = "渠道编码", required = true) + @NotNull(message = "渠道编码不能为空") + private String code; + + @ApiModelProperty(value = "开启状态", required = true) + @NotNull(message = "开启状态不能为空") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "渠道费率,单位:百分比", required = true) + @NotNull(message = "渠道费率,单位:百分比不能为空") + private Double feeRate; + + @ApiModelProperty(value = "商户编号", required = true) + @NotNull(message = "商户编号不能为空") + private Long merchantId; + + @ApiModelProperty(value = "应用编号", required = true) + @NotNull(message = "应用编号不能为空") + private Long appId; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java new file mode 100644 index 0000000..5852f9b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelCreateReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotBlank; + +@ApiModel("管理后台 - 支付渠道 创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayChannelCreateReqVO extends PayChannelBaseVO { + + @ApiModelProperty(value = "渠道配置的 json 字符串") + @NotBlank(message = "渠道配置不能为空") + private String config; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExcelVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExcelVO.java new file mode 100644 index 0000000..780abb1 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExcelVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; + +import com.alibaba.excel.annotation.ExcelProperty; + +/** + * 支付渠道 Excel VO + * + * @author 芋艿 + */ +@Data +public class PayChannelExcelVO { + + @ExcelProperty("商户编号") + private Long id; + + @ExcelProperty("渠道编码") + private String code; + + @ExcelProperty("开启状态") + private Integer status; + + @ExcelProperty("备注") + private String remark; + + @ExcelProperty("渠道费率,单位:百分比") + private Double feeRate; + + @ExcelProperty("商户编号") + private Long merchantId; + + @ExcelProperty("应用编号") + private Long appId; + + /** + * todo @芋艿 mapStruct 存在转换问题 + * java: Can't map property "PayClientConfig payChannelDO.config" to "String payChannelExcelVO.config". + * Consider to declare/implement a mapping method: "String map(PayClientConfig value)". + */ + /// @ExcelProperty("支付渠道配置") + /// private String config; + + @ExcelProperty("创建时间") + private Date createTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java new file mode 100644 index 0000000..d4d6e66 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelExportReqVO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel(value = "管理后台 - 支付渠道 Excel 导出 Request VO", description = "参数和 PayChannelPageReqVO 是一致的") +@Data +public class PayChannelExportReqVO { + + @ApiModelProperty(value = "渠道编码") + private String code; + + @ApiModelProperty(value = "开启状态") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "渠道费率,单位:百分比") + private Double feeRate; + + @ApiModelProperty(value = "商户编号") + private Long merchantId; + + @ApiModelProperty(value = "应用编号") + private Long appId; + + @ApiModelProperty(value = "支付渠道配置") + private String config; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java new file mode 100644 index 0000000..29995d0 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelPageReqVO.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("管理后台 - 支付渠道 分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayChannelPageReqVO extends PageParam { + + @ApiModelProperty(value = "渠道编码") + private String code; + + @ApiModelProperty(value = "开启状态") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @ApiModelProperty(value = "渠道费率,单位:百分比") + private Double feeRate; + + @ApiModelProperty(value = "商户编号") + private Long merchantId; + + @ApiModelProperty(value = "应用编号") + private Long appId; + + @ApiModelProperty(value = "支付渠道配置") + private String config; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java new file mode 100644 index 0000000..b2644f4 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelRespVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; + +@ApiModel("管理后台 - 支付渠道 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayChannelRespVO extends PayChannelBaseVO { + + @ApiModelProperty(value = "商户编号", required = true) + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + + @ApiModelProperty(value = "配置", required = true) + private String config; +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java new file mode 100644 index 0000000..c216de9 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/channel/PayChannelUpdateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel; + +import lombok.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +@ApiModel("管理后台 - 支付渠道 更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayChannelUpdateReqVO extends PayChannelBaseVO { + + @ApiModelProperty(value = "商户编号", required = true) + @NotNull(message = "商户编号不能为空") + private Long id; + + @ApiModelProperty(value = "渠道配置的json字符串") + @NotBlank(message = "渠道配置不能为空") + private String config; +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java new file mode 100644 index 0000000..1052fdd --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantBaseVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** +* 支付商户信息 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class PayMerchantBaseVO { + + @ApiModelProperty(value = "商户全称", required = true) + @NotNull(message = "商户全称不能为空") + private String name; + + @ApiModelProperty(value = "商户简称", required = true) + @NotNull(message = "商户简称不能为空") + private String shortName; + + @ApiModelProperty(value = "开启状态", required = true) + @NotNull(message = "开启状态不能为空") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java new file mode 100644 index 0000000..018db18 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantCreateReqVO.java @@ -0,0 +1,12 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; + +import lombok.*; +import io.swagger.annotations.*; + +@ApiModel("管理后台 - 支付商户信息创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayMerchantCreateReqVO extends PayMerchantBaseVO { + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExcelVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExcelVO.java new file mode 100644 index 0000000..b399a11 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExcelVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 支付商户信息 Excel VO + * + * @author 芋艿 + */ +@Data +public class PayMerchantExcelVO { + + @ExcelProperty("商户编号") + private Long id; + + @ExcelProperty("商户号") + private String no; + + @ExcelProperty("商户全称") + private String name; + + @ExcelProperty("商户简称") + private String shortName; + + @ExcelProperty(value = "开启状态",converter = DictConvert.class) + @DictFormat("sys_common_status") + private Integer status; + + @ExcelProperty("备注") + private String remark; + + @ExcelProperty("创建时间") + private Date createTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java new file mode 100644 index 0000000..680b04b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantExportReqVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel(value = "管理后台 - 支付商户信息 Excel 导出 Request VO", description = "参数和 PayMerchantPageReqVO 是一致的") +@Data +public class PayMerchantExportReqVO { + + @ApiModelProperty(value = "商户号") + private String no; + + @ApiModelProperty(value = "商户全称") + private String name; + + @ApiModelProperty(value = "商户简称") + private String shortName; + + @ApiModelProperty(value = "开启状态") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java new file mode 100644 index 0000000..241287c --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantPageReqVO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; + +import lombok.*; +import java.util.*; +import io.swagger.annotations.*; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import org.springframework.format.annotation.DateTimeFormat; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("管理后台 - 支付商户信息分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayMerchantPageReqVO extends PageParam { + + @ApiModelProperty(value = "商户号") + private String no; + + @ApiModelProperty(value = "商户全称") + private String name; + + @ApiModelProperty(value = "商户简称") + private String shortName; + + @ApiModelProperty(value = "开启状态") + private Integer status; + + @ApiModelProperty(value = "备注") + private String remark; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java new file mode 100644 index 0000000..a27c591 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantRespVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +@ApiModel("管理后台 - 支付商户信息 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayMerchantRespVO extends PayMerchantBaseVO { + + @ApiModelProperty(value = "商户编号", required = true) + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + + @ApiModelProperty(value = "商户号", required = true, example = "M233666999") + private String no; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java new file mode 100644 index 0000000..d270a3d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateReqVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; + +import lombok.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +@ApiModel("管理后台 - 支付商户信息更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayMerchantUpdateReqVO extends PayMerchantBaseVO { + + @ApiModelProperty(value = "商户编号", required = true) + @NotNull(message = "商户编号不能为空") + private Long id; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java new file mode 100644 index 0000000..39e26b8 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/merchant/vo/merchant/PayMerchantUpdateStatusReqVO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@ApiModel("管理后台 - 商户更新状态 Request VO") +@Data +public class PayMerchantUpdateStatusReqVO { + + @ApiModelProperty(value = "商户编号", required = true, example = "1024") + @NotNull(message = "商户编号不能为空") + private Long id; + + @ApiModelProperty(value = "状态", required = true, example = "1", notes = "见 SysCommonStatusEnum 枚举") + @NotNull(message = "状态不能为空") + private Integer status; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java new file mode 100755 index 0000000..2219204 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java @@ -0,0 +1,158 @@ +package cn.iocoder.yudao.module.pay.controller.admin.order; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; +import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.service.merchant.PayAppService; +import cn.iocoder.yudao.module.pay.service.merchant.PayMerchantService; +import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; + +@Api(tags = "管理后台 - 支付订单") +@RestController +@RequestMapping("/pay/order") +@Validated +public class PayOrderController { + + @Resource + private PayOrderService orderService; + @Resource + private PayOrderExtensionService orderExtensionService; + @Resource + private PayMerchantService merchantService; + @Resource + private PayAppService appService; + + @GetMapping("/get") + @ApiOperation("获得支付订单") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:order:query')") + public CommonResult getOrder(@RequestParam("id") Long id) { + PayOrderDO order = orderService.getOrder(id); + if (ObjectUtil.isNull(order)) { + return success(new PayOrderDetailsRespVO()); + } + + PayMerchantDO merchantDO = merchantService.getMerchant(order.getMerchantId()); + PayAppDO appDO = appService.getApp(order.getAppId()); + PayChannelEnum channelEnum = PayChannelEnum.getByCode(order.getChannelCode()); + + // TODO @aquan:文案,都是前端 format; + PayOrderDetailsRespVO respVO = PayOrderConvert.INSTANCE.orderDetailConvert(order); + respVO.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); + respVO.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); + respVO.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); + + PayOrderExtensionDO extensionDO = orderExtensionService.getOrderExtension(order.getSuccessExtensionId()); + if (ObjectUtil.isNotNull(extensionDO)) { + respVO.setPayOrderExtension(PayOrderConvert.INSTANCE.orderDetailExtensionConvert(extensionDO)); + } + + return success(respVO); + } + + @GetMapping("/page") + @ApiOperation("获得支付订单分页") + @PreAuthorize("@ss.hasPermission('pay:order:query')") + public CommonResult> getOrderPage(@Valid PayOrderPageReqVO pageVO) { + PageResult pageResult = orderService.getOrderPage(pageVO); + if (CollectionUtil.isEmpty(pageResult.getList())) { + return success(new PageResult<>(pageResult.getTotal())); + } + + // 处理商户ID数据 + Map merchantMap = merchantService.getMerchantMap( + CollectionUtils.convertList(pageResult.getList(), PayOrderDO::getMerchantId)); + // 处理应用ID数据 + Map appMap = appService.getAppMap( + CollectionUtils.convertList(pageResult.getList(), PayOrderDO::getAppId)); + + List pageList = new ArrayList<>(pageResult.getList().size()); + pageResult.getList().forEach(c -> { + PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId()); + PayAppDO appDO = appMap.get(c.getAppId()); + PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode()); + + PayOrderPageItemRespVO orderItem = PayOrderConvert.INSTANCE.pageConvertItemPage(c); + orderItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); + orderItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); + orderItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); + pageList.add(orderItem); + }); + return success(new PageResult<>(pageList, pageResult.getTotal())); + } + + @GetMapping("/export-excel") + @ApiOperation("导出支付订单Excel") + @PreAuthorize("@ss.hasPermission('pay:order:export')") + @OperateLog(type = EXPORT) + public void exportOrderExcel(@Valid PayOrderExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + + List list = orderService.getOrderList(exportReqVO); + if (CollectionUtil.isEmpty(list)) { + ExcelUtils.write(response, "支付订单.xls", "数据", + PayOrderExcelVO.class, new ArrayList<>()); + } + + // 处理商户ID数据 + Map merchantMap = merchantService.getMerchantMap( + CollectionUtils.convertList(list, PayOrderDO::getMerchantId)); + // 处理应用ID数据 + Map appMap = appService.getAppMap( + CollectionUtils.convertList(list, PayOrderDO::getAppId)); + // 处理扩展订单数据 + Map orderExtensionMap = orderExtensionService + .getOrderExtensionMap(CollectionUtils.convertList(list, PayOrderDO::getSuccessExtensionId)); + + List excelDatum = new ArrayList<>(list.size()); + list.forEach(c -> { + PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId()); + PayAppDO appDO = appMap.get(c.getAppId()); + PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode()); + PayOrderExtensionDO orderExtensionDO = orderExtensionMap.get(c.getSuccessExtensionId()); + + PayOrderExcelVO excelItem = PayOrderConvert.INSTANCE.excelConvert(c); + excelItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); + excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); + excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); + excelItem.setNo(ObjectUtil.isNotNull(orderExtensionDO) ? orderExtensionDO.getNo() : ""); + excelDatum.add(excelItem); + }); + + // 导出 Excel + ExcelUtils.write(response, "支付订单.xls", "数据", PayOrderExcelVO.class, excelDatum); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java new file mode 100755 index 0000000..1064720 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderBaseVO.java @@ -0,0 +1,107 @@ +package cn.iocoder.yudao.module.pay.controller.admin.order.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * 支付订单 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + * + * @author aquan + */ +@Data +public class PayOrderBaseVO { + + @ApiModelProperty(value = "商户编号", required = true) + @NotNull(message = "商户编号不能为空") + private Long merchantId; + + @ApiModelProperty(value = "应用编号", required = true) + @NotNull(message = "应用编号不能为空") + private Long appId; + + @ApiModelProperty(value = "渠道编号") + private Long channelId; + + @ApiModelProperty(value = "渠道编码") + private String channelCode; + + @ApiModelProperty(value = "商户订单编号", required = true) + @NotNull(message = "商户订单编号不能为空") + private String merchantOrderId; + + @ApiModelProperty(value = "商品标题", required = true) + @NotNull(message = "商品标题不能为空") + private String subject; + + @ApiModelProperty(value = "商品描述", required = true) + @NotNull(message = "商品描述不能为空") + private String body; + + @ApiModelProperty(value = "异步通知地址", required = true) + @NotNull(message = "异步通知地址不能为空") + private String notifyUrl; + + @ApiModelProperty(value = "通知商户支付结果的回调状态", required = true) + @NotNull(message = "通知商户支付结果的回调状态不能为空") + private Integer notifyStatus; + + @ApiModelProperty(value = "支付金额,单位:分", required = true) + @NotNull(message = "支付金额,单位:分不能为空") + private Long amount; + + @ApiModelProperty(value = "渠道手续费,单位:百分比") + private Double channelFeeRate; + + @ApiModelProperty(value = "渠道手续金额,单位:分") + private Long channelFeeAmount; + + @ApiModelProperty(value = "支付状态", required = true) + @NotNull(message = "支付状态不能为空") + private Integer status; + + @ApiModelProperty(value = "用户 IP", required = true) + @NotNull(message = "用户 IP不能为空") + private String userIp; + + @ApiModelProperty(value = "订单失效时间", required = true) + @NotNull(message = "订单失效时间不能为空") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date expireTime; + + @ApiModelProperty(value = "订单支付成功时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date successTime; + + @ApiModelProperty(value = "订单支付通知时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date notifyTime; + + @ApiModelProperty(value = "支付成功的订单拓展单编号") + private Long successExtensionId; + + @ApiModelProperty(value = "退款状态", required = true) + @NotNull(message = "退款状态不能为空") + private Integer refundStatus; + + @ApiModelProperty(value = "退款次数", required = true) + @NotNull(message = "退款次数不能为空") + private Integer refundTimes; + + @ApiModelProperty(value = "退款总金额,单位:分", required = true) + @NotNull(message = "退款总金额,单位:分不能为空") + private Long refundAmount; + + @ApiModelProperty(value = "渠道用户编号") + private String channelUserId; + + @ApiModelProperty(value = "渠道订单号") + private String channelOrderNo; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java new file mode 100644 index 0000000..6bf7152 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderDetailsRespVO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.pay.controller.admin.order.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +@ApiModel("管理后台 - 支付订单详细信息 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayOrderDetailsRespVO extends PayOrderBaseVO { + + @ApiModelProperty(value = "支付订单编号") + private Long id; + + @ApiModelProperty(value = "商户名称") + private String merchantName; + + @ApiModelProperty(value = "应用名称") + private String appName; + + @ApiModelProperty(value = "渠道编号名称") + private String channelCodeName; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + /** + * 支付订单扩展 + */ + private PayOrderExtension payOrderExtension; + + @Data + @ApiModel("支付订单扩展") + public static class PayOrderExtension { + + @ApiModelProperty(value = "支付订单号") + private String no; + + @ApiModelProperty(value = "支付异步通知的内容") + private String channelNotifyData; + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExcelVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExcelVO.java new file mode 100755 index 0000000..c620e2d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExcelVO.java @@ -0,0 +1,91 @@ +package cn.iocoder.yudao.module.pay.controller.admin.order.vo; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.pay.enums.DictTypeConstants; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 支付订单Excel VO + * + * @author aquan + */ +@Data +public class PayOrderExcelVO { + + @ExcelProperty("支付订单编号") + private Long id; + + @ExcelProperty(value = "商户名称") + private String merchantName; + + @ExcelProperty(value = "应用名称") + private String appName; + + @ExcelProperty("商品标题") + private String subject; + + @ExcelProperty("商户订单编号") + private String merchantOrderId; + + @ExcelProperty("渠道订单号") + private String channelOrderNo; + + @ExcelProperty(value = "支付订单号") + private String no; + + @ExcelProperty("支付金额,单位:元") + private String amount; + + @ExcelProperty("渠道手续金额,单位:元") + private String channelFeeAmount; + + @ExcelProperty("渠道手续费,单位:百分比") + private String channelFeeRate; + + @DictFormat(DictTypeConstants.PAY_ORDER_STATUS) + @ExcelProperty(value = "支付状态", converter = DictConvert.class) + private Integer status; + + @DictFormat(DictTypeConstants.PAY_ORDER_NOTIFY_STATUS) + @ExcelProperty(value = "通知商户支付结果的回调状态", converter = DictConvert.class) + private Integer notifyStatus; + + @ExcelProperty("异步通知地址") + private String notifyUrl; + + @ExcelProperty("创建时间") + private Date createTime; + + @ExcelProperty("订单支付成功时间") + private Date successTime; + + @ExcelProperty("订单失效时间") + private Date expireTime; + + @ExcelProperty("订单支付通知时间") + private Date notifyTime; + + @ExcelProperty(value = "渠道编号名称") + private String channelCodeName; + + @ExcelProperty("用户 IP") + private String userIp; + + @DictFormat(DictTypeConstants.PAY_ORDER_REFUND_STATUS) + @ExcelProperty(value = "退款状态", converter = DictConvert.class) + private Integer refundStatus; + + @ExcelProperty("退款次数") + private Integer refundTimes; + + @ExcelProperty("退款总金额,单位:元") + private String refundAmount; + + @ExcelProperty("商品描述") + private String body; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java new file mode 100755 index 0000000..c079ea1 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderExportReqVO.java @@ -0,0 +1,108 @@ +package cn.iocoder.yudao.module.pay.controller.admin.order.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel(value = "管理后台 - 支付订单 Excel 导出 Request VO", description = "参数和 PayOrderPageReqVO 是一致的") +@Data +public class PayOrderExportReqVO { + + @ApiModelProperty(value = "商户编号") + private Long merchantId; + + @ApiModelProperty(value = "应用编号") + private Long appId; + + @ApiModelProperty(value = "渠道编号") + private Long channelId; + + @ApiModelProperty(value = "渠道编码") + private String channelCode; + + @ApiModelProperty(value = "商户订单编号") + private String merchantOrderId; + + @ApiModelProperty(value = "商品标题") + private String subject; + + @ApiModelProperty(value = "商品描述") + private String body; + + @ApiModelProperty(value = "异步通知地址") + private String notifyUrl; + + @ApiModelProperty(value = "通知商户支付结果的回调状态") + private Integer notifyStatus; + + @ApiModelProperty(value = "支付金额,单位:分") + private Long amount; + + @ApiModelProperty(value = "渠道手续费,单位:百分比") + private Double channelFeeRate; + + @ApiModelProperty(value = "渠道手续金额,单位:分") + private Long channelFeeAmount; + + @ApiModelProperty(value = "支付状态") + private Integer status; + + @ApiModelProperty(value = "用户 IP") + private String userIp; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始订单失效时间") + private Date beginExpireTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束订单失效时间") + private Date endExpireTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始订单支付成功时间") + private Date beginSuccessTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束订单支付成功时间") + private Date endSuccessTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始订单支付通知时间") + private Date beginNotifyTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束订单支付通知时间") + private Date endNotifyTime; + + @ApiModelProperty(value = "支付成功的订单拓展单编号") + private Long successExtensionId; + + @ApiModelProperty(value = "退款状态") + private Integer refundStatus; + + @ApiModelProperty(value = "退款次数") + private Integer refundTimes; + + @ApiModelProperty(value = "退款总金额,单位:分") + private Long refundAmount; + + @ApiModelProperty(value = "渠道用户编号") + private String channelUserId; + + @ApiModelProperty(value = "渠道订单号") + private String channelOrderNo; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java new file mode 100755 index 0000000..3c0b4e6 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageItemRespVO.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.pay.controller.admin.order.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +@ApiModel("管理后台 - 支付订单分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayOrderPageItemRespVO extends PayOrderBaseVO { + + @ApiModelProperty(value = "支付订单编号", required = true) + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + + @ApiModelProperty(value = "商户名称") + private String merchantName; + + @ApiModelProperty(value = "应用名称") + private String appName; + + @ApiModelProperty(value = "渠道名称") + private String channelCodeName; + + @ApiModelProperty(value = "支付订单号") + private String no; + + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java new file mode 100755 index 0000000..5787ba2 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderPageReqVO.java @@ -0,0 +1,113 @@ +package cn.iocoder.yudao.module.pay.controller.admin.order.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("管理后台 - 支付订单分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayOrderPageReqVO extends PageParam { + + @ApiModelProperty(value = "商户编号") + private Long merchantId; + + @ApiModelProperty(value = "应用编号") + private Long appId; + + @ApiModelProperty(value = "渠道编号") + private Long channelId; + + @ApiModelProperty(value = "渠道编码") + private String channelCode; + + @ApiModelProperty(value = "商户订单编号") + private String merchantOrderId; + + @ApiModelProperty(value = "商品标题") + private String subject; + + @ApiModelProperty(value = "商品描述") + private String body; + + @ApiModelProperty(value = "异步通知地址") + private String notifyUrl; + + @ApiModelProperty(value = "通知商户支付结果的回调状态") + private Integer notifyStatus; + + @ApiModelProperty(value = "支付金额,单位:分") + private Long amount; + + @ApiModelProperty(value = "渠道手续费,单位:百分比") + private Double channelFeeRate; + + @ApiModelProperty(value = "渠道手续金额,单位:分") + private Long channelFeeAmount; + + @ApiModelProperty(value = "支付状态") + private Integer status; + + @ApiModelProperty(value = "用户 IP") + private String userIp; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始订单失效时间") + private Date beginExpireTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束订单失效时间") + private Date endExpireTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始订单支付成功时间") + private Date beginSuccessTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束订单支付成功时间") + private Date endSuccessTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始订单支付通知时间") + private Date beginNotifyTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束订单支付通知时间") + private Date endNotifyTime; + + @ApiModelProperty(value = "支付成功的订单拓展单编号") + private Long successExtensionId; + + @ApiModelProperty(value = "退款状态") + private Integer refundStatus; + + @ApiModelProperty(value = "退款次数") + private Integer refundTimes; + + @ApiModelProperty(value = "退款总金额,单位:分") + private Long refundAmount; + + @ApiModelProperty(value = "渠道用户编号") + private String channelUserId; + + @ApiModelProperty(value = "渠道订单号") + private String channelOrderNo; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java new file mode 100755 index 0000000..29d0cb6 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/vo/PayOrderRespVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.pay.controller.admin.order.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +@ApiModel("管理后台 - 支付订单 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayOrderRespVO extends PayOrderBaseVO { + + @ApiModelProperty(value = "支付订单编号", required = true) + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java new file mode 100755 index 0000000..58cb24f --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/PayRefundController.java @@ -0,0 +1,156 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.*; +import cn.iocoder.yudao.module.pay.convert.refund.PayRefundConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.service.merchant.PayAppService; +import cn.iocoder.yudao.module.pay.service.merchant.PayMerchantService; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; + +@Api(tags = "管理后台 - 退款订单") +@RestController +@RequestMapping("/pay/refund") +@Validated +public class PayRefundController { + + @Resource + private PayRefundService refundService; + @Resource + private PayMerchantService merchantService; + @Resource + private PayAppService appService; + @Resource + private PayOrderService orderService; + + @GetMapping("/get") + @ApiOperation("获得退款订单") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('pay:refund:query')") + public CommonResult getRefund(@RequestParam("id") Long id) { + PayRefundDO refund = refundService.getRefund(id); + if (ObjectUtil.isNull(refund)) { + return success(new PayRefundDetailsRespVO()); + } + + PayMerchantDO merchantDO = merchantService.getMerchant(refund.getMerchantId()); + PayAppDO appDO = appService.getApp(refund.getAppId()); + PayChannelEnum channelEnum = PayChannelEnum.getByCode(refund.getChannelCode()); + PayOrderDO orderDO = orderService.getOrder(refund.getOrderId()); + + PayRefundDetailsRespVO refundDetail = PayRefundConvert.INSTANCE.refundDetailConvert(refund); + refundDetail.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); + refundDetail.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); + refundDetail.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); + refundDetail.setSubject(orderDO.getSubject()); + + return success(refundDetail); + } + + @GetMapping("/page") + @ApiOperation("获得退款订单分页") + @PreAuthorize("@ss.hasPermission('pay:refund:query')") + public CommonResult> getRefundPage(@Valid PayRefundPageReqVO pageVO) { + PageResult pageResult = refundService.getRefundPage(pageVO); + if (CollectionUtil.isEmpty(pageResult.getList())) { + return success(new PageResult<>(pageResult.getTotal())); + } + + // 处理商户ID数据 + Map merchantMap = merchantService.getMerchantMap( + CollectionUtils.convertList(pageResult.getList(), PayRefundDO::getMerchantId)); + // 处理应用ID数据 + Map appMap = appService.getAppMap( + CollectionUtils.convertList(pageResult.getList(), PayRefundDO::getAppId)); + List list = new ArrayList<>(pageResult.getList().size()); + pageResult.getList().forEach(c -> { + PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId()); + PayAppDO appDO = appMap.get(c.getAppId()); + PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode()); + + PayRefundPageItemRespVO item = PayRefundConvert.INSTANCE.pageItemConvert(c); + + item.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); + item.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); + item.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); + list.add(item); + }); + + return success(new PageResult<>(list, pageResult.getTotal())); + } + + @GetMapping("/export-excel") + @ApiOperation("导出退款订单 Excel") + @PreAuthorize("@ss.hasPermission('pay:refund:export')") + @OperateLog(type = EXPORT) + public void exportRefundExcel(@Valid PayRefundExportReqVO exportReqVO, + HttpServletResponse response) throws IOException { + + List list = refundService.getRefundList(exportReqVO); + if (CollectionUtil.isEmpty(list)) { + ExcelUtils.write(response, "退款订单.xls", "数据", + PayRefundExcelVO.class, new ArrayList<>()); + } + + // 处理商户ID数据 + Map merchantMap = merchantService.getMerchantMap( + CollectionUtils.convertList(list, PayRefundDO::getMerchantId)); + // 处理应用ID数据 + Map appMap = appService.getAppMap( + CollectionUtils.convertList(list, PayRefundDO::getAppId)); + + List excelDatum = new ArrayList<>(list.size()); + // 处理商品名称数据 + Map orderMap = orderService.getOrderSubjectMap( + CollectionUtils.convertList(list, PayRefundDO::getOrderId)); + + list.forEach(c -> { + PayMerchantDO merchantDO = merchantMap.get(c.getMerchantId()); + PayAppDO appDO = appMap.get(c.getAppId()); + PayChannelEnum channelEnum = PayChannelEnum.getByCode(c.getChannelCode()); + + PayRefundExcelVO excelItem = PayRefundConvert.INSTANCE.excelConvert(c); + excelItem.setMerchantName(ObjectUtil.isNotNull(merchantDO) ? merchantDO.getName() : "未知商户"); + excelItem.setAppName(ObjectUtil.isNotNull(appDO) ? appDO.getName() : "未知应用"); + excelItem.setChannelCodeName(ObjectUtil.isNotNull(channelEnum) ? channelEnum.getName() : "未知渠道"); + excelItem.setSubject(orderMap.get(c.getOrderId()).getSubject()); + + excelDatum.add(excelItem); + }); + + // 导出 Excel + ExcelUtils.write(response, "退款订单.xls", "数据", PayRefundExcelVO.class, excelDatum); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java new file mode 100755 index 0000000..594496c --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundBaseVO.java @@ -0,0 +1,110 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** +* 退款订单 Base VO,提供给添加、修改、详细的子 VO 使用 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 +*/ +@Data +public class PayRefundBaseVO { + + @ApiModelProperty(value = "商户编号", required = true) + @NotNull(message = "商户编号不能为空") + private Long merchantId; + + @ApiModelProperty(value = "应用编号", required = true) + @NotNull(message = "应用编号不能为空") + private Long appId; + + @ApiModelProperty(value = "渠道编号", required = true) + @NotNull(message = "渠道编号不能为空") + private Long channelId; + + @ApiModelProperty(value = "渠道编码", required = true) + @NotNull(message = "渠道编码不能为空") + private String channelCode; + + @ApiModelProperty(value = "支付订单编号 pay_order 表id", required = true) + @NotNull(message = "支付订单编号 pay_order 表id不能为空") + private Long orderId; + + @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段", required = true) + @NotNull(message = "交易订单号 pay_extension 表no 字段不能为空") + private String tradeNo; + + @ApiModelProperty(value = "商户订单编号(商户系统生成)", required = true) + @NotNull(message = "商户订单编号(商户系统生成)不能为空") + private String merchantOrderId; + + @ApiModelProperty(value = "商户退款订单号(商户系统生成)", required = true) + @NotNull(message = "商户退款订单号(商户系统生成)不能为空") + private String merchantRefundNo; + + @ApiModelProperty(value = "异步通知商户地址", required = true) + @NotNull(message = "异步通知商户地址不能为空") + private String notifyUrl; + + @ApiModelProperty(value = "通知商户退款结果的回调状态", required = true) + @NotNull(message = "通知商户退款结果的回调状态不能为空") + private Integer notifyStatus; + + @ApiModelProperty(value = "退款状态", required = true) + @NotNull(message = "退款状态不能为空") + private Integer status; + + @ApiModelProperty(value = "退款类型(部分退款,全部退款)", required = true) + @NotNull(message = "退款类型(部分退款,全部退款)不能为空") + private Integer type; + + @ApiModelProperty(value = "支付金额,单位分", required = true) + @NotNull(message = "支付金额,单位分不能为空") + private Long payAmount; + + @ApiModelProperty(value = "退款金额,单位分", required = true) + @NotNull(message = "退款金额,单位分不能为空") + private Long refundAmount; + + @ApiModelProperty(value = "退款原因", required = true) + @NotNull(message = "退款原因不能为空") + private String reason; + + @ApiModelProperty(value = "用户 IP") + private String userIp; + + @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应", required = true) + @NotNull(message = "渠道订单号,pay_order 中的channel_order_no 对应不能为空") + private String channelOrderNo; + + @ApiModelProperty(value = "渠道退款单号,渠道返回") + private String channelRefundNo; + + @ApiModelProperty(value = "渠道调用报错时,错误码") + private String channelErrorCode; + + @ApiModelProperty(value = "渠道调用报错时,错误信息") + private String channelErrorMsg; + + @ApiModelProperty(value = "支付渠道的额外参数") + private String channelExtras; + + @ApiModelProperty(value = "退款失效时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date expireTime; + + @ApiModelProperty(value = "退款成功时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date successTime; + + @ApiModelProperty(value = "退款通知时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private Date notifyTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java new file mode 100755 index 0000000..cc09111 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundCreateReqVO.java @@ -0,0 +1,12 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import lombok.*; +import io.swagger.annotations.*; + +@ApiModel("管理后台 - 退款订单创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayRefundCreateReqVO extends PayRefundBaseVO { + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java new file mode 100755 index 0000000..e8a70ec --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundDetailsRespVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +@ApiModel("管理后台 - 退款订单详情 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayRefundDetailsRespVO extends PayRefundBaseVO { + + @ApiModelProperty(value = "支付退款编号", required = true) + private Long id; + + @ApiModelProperty(value = "商户名称") + private String merchantName; + + @ApiModelProperty(value = "应用名称") + private String appName; + + @ApiModelProperty(value = "渠道编号名称") + private String channelCodeName; + + @NotNull(message = "商品标题不能为空") + private String subject; + + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "更新时间") + private Date updateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExcelVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExcelVO.java new file mode 100755 index 0000000..75e72c8 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExcelVO.java @@ -0,0 +1,88 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.module.pay.enums.DictTypeConstants; +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.util.Date; + +/** + * 退款订单 Excel VO + * + * @author aquan + */ +@Data +public class PayRefundExcelVO { + + @ExcelProperty("支付退款编号") + private Long id; + + @ExcelProperty("商品名称") + private String subject; + + @ExcelProperty(value = "商户名称") + private String merchantName; + + @ExcelProperty(value = "应用名称") + private String appName; + + @ExcelProperty(value = "渠道编号名称") + private String channelCodeName; + + @ExcelProperty("交易订单号") + private String tradeNo; + + @ExcelProperty("商户订单编号") + private String merchantOrderId; + + @ExcelProperty("商户退款订单号") + private String merchantRefundNo; + + @ExcelProperty("异步通知商户地址") + private String notifyUrl; + + @DictFormat(DictTypeConstants.PAY_ORDER_NOTIFY_STATUS) + @ExcelProperty(value = "商户退款结果回调状态", converter = DictConvert.class) + private Integer notifyStatus; + + @DictFormat(DictTypeConstants.PAY_REFUND_ORDER_STATUS) + @ExcelProperty(value = "退款状态", converter = DictConvert.class) + private Integer status; + + @DictFormat(DictTypeConstants.PAY_REFUND_ORDER_TYPE) + @ExcelProperty(value = "退款类型", converter = DictConvert.class) + private Integer type; + + @ExcelProperty("支付金额,单位:元") + private String payAmount; + + @ExcelProperty("退款金额,单位:元") + private String refundAmount; + + @ExcelProperty("退款原因") + private String reason; + + @ExcelProperty("用户付款 IP") + private String userIp; + + @ExcelProperty("渠道订单号") + private String channelOrderNo; + + @ExcelProperty("渠道退款单号") + private String channelRefundNo; + + @ExcelProperty("创建时间") + private Date createTime; + + @ExcelProperty("退款成功时间") + private Date successTime; + + @ExcelProperty("退款通知时间") + private Date notifyTime; + + @ExcelProperty("退款失效时间") + private Date expireTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java new file mode 100755 index 0000000..c049823 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundExportReqVO.java @@ -0,0 +1,111 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel(value = "管理后台 - 退款订单 Excel 导出 Request VO", description = "参数和 PayRefundPageReqVO 是一致的") +@Data +public class PayRefundExportReqVO { + + @ApiModelProperty(value = "商户编号") + private Long merchantId; + + @ApiModelProperty(value = "应用编号") + private Long appId; + + @ApiModelProperty(value = "渠道编号") + private Long channelId; + + @ApiModelProperty(value = "渠道编码") + private String channelCode; + + @ApiModelProperty(value = "支付订单编号 pay_order 表id") + private Long orderId; + + @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段") + private String tradeNo; + + @ApiModelProperty(value = "商户订单编号(商户系统生成)") + private String merchantOrderId; + + @ApiModelProperty(value = "商户退款订单号(商户系统生成)") + private String merchantRefundNo; + + @ApiModelProperty(value = "异步通知商户地址") + private String notifyUrl; + + @ApiModelProperty(value = "通知商户退款结果的回调状态") + private Integer notifyStatus; + + @ApiModelProperty(value = "退款状态") + private Integer status; + + @ApiModelProperty(value = "退款类型(部分退款,全部退款)") + private Integer type; + + @ApiModelProperty(value = "支付金额,单位分") + private Long payAmount; + + @ApiModelProperty(value = "退款金额,单位分") + private Long refundAmount; + + @ApiModelProperty(value = "退款原因") + private String reason; + + @ApiModelProperty(value = "用户 IP") + private String userIp; + + @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应") + private String channelOrderNo; + + @ApiModelProperty(value = "渠道退款单号,渠道返回") + private String channelRefundNo; + + @ApiModelProperty(value = "渠道调用报错时,错误码") + private String channelErrorCode; + + @ApiModelProperty(value = "渠道调用报错时,错误信息") + private String channelErrorMsg; + + @ApiModelProperty(value = "支付渠道的额外参数") + private String channelExtras; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始退款失效时间") + private Date beginExpireTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束退款失效时间") + private Date endExpireTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始退款成功时间") + private Date beginSuccessTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束退款成功时间") + private Date endSuccessTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始退款通知时间") + private Date beginNotifyTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束退款通知时间") + private Date endNotifyTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java new file mode 100755 index 0000000..03fe650 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageItemRespVO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +@ApiModel("管理后台 - 退款订单分页查询 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayRefundPageItemRespVO extends PayRefundBaseVO { + + @ApiModelProperty(value = "支付订单编号", required = true) + private Long id; + + @ApiModelProperty(value = "商户名称") + private String merchantName; + + @ApiModelProperty(value = "应用名称") + private String appName; + + @ApiModelProperty(value = "渠道名称") + private String channelCodeName; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java new file mode 100755 index 0000000..7827200 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundPageReqVO.java @@ -0,0 +1,116 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@ApiModel("管理后台 - 退款订单分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayRefundPageReqVO extends PageParam { + + @ApiModelProperty(value = "商户编号") + private Long merchantId; + + @ApiModelProperty(value = "应用编号") + private Long appId; + + @ApiModelProperty(value = "渠道编号") + private Long channelId; + + @ApiModelProperty(value = "渠道编码") + private String channelCode; + + @ApiModelProperty(value = "支付订单编号 pay_order 表id") + private Long orderId; + + @ApiModelProperty(value = "交易订单号 pay_extension 表no 字段") + private String tradeNo; + + @ApiModelProperty(value = "商户订单编号(商户系统生成)") + private String merchantOrderId; + + @ApiModelProperty(value = "商户退款订单号(商户系统生成)") + private String merchantRefundNo; + + @ApiModelProperty(value = "异步通知商户地址") + private String notifyUrl; + + @ApiModelProperty(value = "通知商户退款结果的回调状态") + private Integer notifyStatus; + + @ApiModelProperty(value = "退款状态") + private Integer status; + + @ApiModelProperty(value = "退款类型(部分退款,全部退款)") + private Integer type; + + @ApiModelProperty(value = "支付金额,单位分") + private Long payAmount; + + @ApiModelProperty(value = "退款金额,单位分") + private Long refundAmount; + + @ApiModelProperty(value = "退款原因") + private String reason; + + @ApiModelProperty(value = "用户 IP") + private String userIp; + + @ApiModelProperty(value = "渠道订单号,pay_order 中的channel_order_no 对应") + private String channelOrderNo; + + @ApiModelProperty(value = "渠道退款单号,渠道返回") + private String channelRefundNo; + + @ApiModelProperty(value = "渠道调用报错时,错误码") + private String channelErrorCode; + + @ApiModelProperty(value = "渠道调用报错时,错误信息") + private String channelErrorMsg; + + @ApiModelProperty(value = "支付渠道的额外参数") + private String channelExtras; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始退款失效时间") + private Date beginExpireTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束退款失效时间") + private Date endExpireTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始退款成功时间") + private Date beginSuccessTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束退款成功时间") + private Date endSuccessTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始退款通知时间") + private Date beginNotifyTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束退款通知时间") + private Date endNotifyTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "开始创建时间") + private Date beginCreateTime; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "结束创建时间") + private Date endCreateTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java new file mode 100755 index 0000000..97445d7 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundRespVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +@ApiModel("管理后台 - 退款订单 Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayRefundRespVO extends PayRefundBaseVO { + + @ApiModelProperty(value = "支付退款编号", required = true) + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java new file mode 100755 index 0000000..b7d5555 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/refund/vo/PayRefundUpdateReqVO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.pay.controller.admin.refund.vo; + +import lombok.*; +import io.swagger.annotations.*; +import javax.validation.constraints.*; + +@ApiModel("管理后台 - 退款订单更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class PayRefundUpdateReqVO extends PayRefundBaseVO { + + @ApiModelProperty(value = "支付退款编号", required = true) + @NotNull(message = "支付退款编号不能为空") + private Long id; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java new file mode 100644 index 0000000..e01f7f4 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java @@ -0,0 +1,122 @@ +package cn.iocoder.yudao.module.pay.controller.app.order; + +import cn.hutool.core.bean.BeanUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.pay.core.client.PayClient; +import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; +import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; +import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitRespDTO; +import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; + +@Api(tags = "用户 APP - 支付订单") +@RestController +@RequestMapping("/pay/order") +@Validated +@Slf4j +public class AppPayOrderController { + + @Resource + private PayOrderService orderService; + @Resource + private PayRefundService refundService; + + @Resource + private PayClientFactory payClientFactory; + + @PostMapping("/submit") + @ApiOperation("提交支付订单") +// @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好 + public CommonResult submitPayOrder(@RequestBody AppPayOrderSubmitReqVO reqVO) { + // 获得订单 + PayOrderDO payOrder = orderService.getOrder(reqVO.getId()); + + // 提交支付 + PayOrderSubmitReqDTO reqDTO = new PayOrderSubmitReqDTO(); + BeanUtil.copyProperties(reqVO, reqDTO, false); + reqDTO.setUserIp(getClientIP()); + reqDTO.setAppId(payOrder.getAppId()); + PayOrderSubmitRespDTO respDTO = orderService.submitPayOrder(reqDTO); + + // 拼接返回 + return success(AppPayOrderSubmitRespVO.builder().invokeResponse(respDTO.getInvokeResponse()).build()); + } + + // ========== 支付渠道的回调 ========== + // TODO @芋艿:是不是放到 notify 模块更合适 + //TODO 芋道源码 换成了统一的地址了 /notify/{channelId},测试通过可以删除 + @PostMapping("/notify/wx-pub/{channelId}") + @ApiOperation("通知微信公众号支付的结果") + public String notifyWxPayOrder(@PathVariable("channelId") Long channelId, + @RequestBody String xmlData) throws Exception { + orderService.notifyPayOrder(channelId, PayNotifyDataDTO.builder().body(xmlData).build()); + return "success"; + } + + /** + * 统一的跳转页面, 支付宝跳转参数说明 + * https://opendocs.alipay.com/open/203/105285#%E5%89%8D%E5%8F%B0%E5%9B%9E%E8%B7%B3%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E + * @param channelId 渠道id + * @return 返回跳转页面 + */ + @GetMapping(value = "/return/{channelId}") + @ApiOperation("渠道统一的支付成功返回地址") + public String returnAliPayOrder(@PathVariable("channelId") Long channelId, @RequestParam Map params){ + //TODO 可以根据渠道和 app_id 返回不同的页面 + log.info("app_id is {}", params.get("app_id")); + return String.format("渠道[%s]支付成功", channelId); + } + + /** + * 统一的渠道支付回调,支付宝的退款回调 + * + * @param channelId 渠道编号 + * @param params form 参数 + * @param originData http request body + * @return 成功返回 "success" + */ + @PostMapping(value = "/notify/{channelId}") + @ApiOperation("渠道统一的支付成功,或退款成功 通知url") + public String notifyChannelPay(@PathVariable("channelId") Long channelId, + @RequestParam Map params, + @RequestBody String originData) throws Exception { + // 校验支付渠道是否存在 + PayClient payClient = payClientFactory.getPayClient(channelId); + if (payClient == null) { + log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channelId); + throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); + } + + // 校验通知数据是否合法 + PayNotifyDataDTO notifyData = PayNotifyDataDTO.builder().params(params).body(originData).build(); + payClient.verifyNotifyData(notifyData); + + // 如果是退款,则发起退款通知 + if (payClient.isRefundNotify(notifyData)) { + refundService.notifyPayRefund(channelId, PayNotifyDataDTO.builder().params(params).body(originData).build()); + return "success"; + } + + // 如果非退款,则发起支付通知 + orderService.notifyPayOrder(channelId, PayNotifyDataDTO.builder().params(params).body(originData).build()); + return "success"; + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java new file mode 100644 index 0000000..6834c38 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.pay.controller.app.order.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Map; + +@ApiModel("用户 APP - 支付订单提交 Request VO") +@Data +@Accessors(chain = true) +public class AppPayOrderSubmitReqVO { + + @ApiModelProperty(value = "支付单编号", required = true, example = "1024") + @NotNull(message = "支付单编号不能为空") + private Long id; + + @ApiModelProperty(value = "支付渠道", required = true, example = "wx_pub") + @NotEmpty(message = "支付渠道不能为空") + private String channelCode; + + @ApiModelProperty(value = "支付渠道的额外参数", notes = "例如说,微信公众号需要传递 openid 参数") + private Map channelExtras; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java new file mode 100644 index 0000000..7fcffd0 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/vo/AppPayOrderSubmitRespVO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.pay.controller.app.order.vo; + +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@ApiModel("用户 APP - 支付订单提交 Response VO") +@Data +@Accessors(chain = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AppPayOrderSubmitRespVO { + + /** + * 调用支付渠道的响应结果 + */ + private Object invokeResponse; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/package-info.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/package-info.java new file mode 100644 index 0000000..333cbe6 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.pay.controller.app; diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java new file mode 100644 index 0000000..42fdc5d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/AppPayRefundController.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.pay.controller.app.refund; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.pay.controller.app.refund.vo.AppPayRefundReqVO; +import cn.iocoder.yudao.module.pay.controller.app.refund.vo.AppPayRefundRespVO; +import cn.iocoder.yudao.module.pay.convert.refund.PayRefundConvert; +import cn.iocoder.yudao.module.pay.service.order.dto.PayRefundReqDTO; +import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import cn.iocoder.yudao.module.pay.util.PaySeqUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; + +@Api(tags = "用户 APP - 退款订单") +@RestController +@RequestMapping("/pay/refund") +@Validated +@Slf4j +public class AppPayRefundController { + + @Resource + private PayRefundService refundService; + + @PostMapping("/refund") + @ApiOperation("提交退款订单") + public CommonResult submitRefundOrder(@RequestBody AppPayRefundReqVO reqVO){ + PayRefundReqDTO req = PayRefundConvert.INSTANCE.convert(reqVO); + req.setUserIp(getClientIP()); + // TODO 测试暂时模拟生成商户退款订单 + if(StrUtil.isEmpty(reqVO.getMerchantRefundId())) { + req.setMerchantRefundId(PaySeqUtils.genMerchantRefundNo()); + } + return success(PayRefundConvert.INSTANCE.convert(refundService.submitRefundOrder(req))); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java new file mode 100644 index 0000000..c810f38 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundReqVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.pay.controller.app.refund.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; + +@ApiModel("用户 APP - 退款订单 Req VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +public class AppPayRefundReqVO { + + @ApiModelProperty(value = "支付订单编号自增", required = true, example = "10") + @NotEmpty(message = "支付订单编号自增") + private Long payOrderId; + + @ApiModelProperty(value = "退款金额", required = true, example = "1") + @NotEmpty(message = "退款金额") + private Long amount; + + @ApiModelProperty(value = "退款原因", required = true, example = "不喜欢") + @NotEmpty(message = "退款原因") + private String reason; + + @ApiModelProperty(value = "商户退款订单号", required = true, example = "MR202111180000000001") + //TODO 测试暂时模拟生成 + //@NotEmpty(message = "商户退款订单号") + private String merchantRefundId; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java new file mode 100644 index 0000000..5342432 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/app/refund/vo/AppPayRefundRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.pay.controller.app.refund.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@ApiModel("用户 APP - 提交退款订单 Response VO") +@Data +@Accessors(chain = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AppPayRefundRespVO { + + @ApiModelProperty(value = "退款订单编号", required = true, example = "10") + private Long refundId; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/package-info.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/package-info.java new file mode 100644 index 0000000..6521227 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/controller/package-info.java @@ -0,0 +1,6 @@ +/** + * 提供 RESTful API 给前端: + * 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目 + * 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分 + */ +package cn.iocoder.yudao.module.pay.controller; diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java new file mode 100644 index 0000000..432699b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/app/PayAppConvert.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.pay.convert.app; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.*; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 支付应用信息 Convert + * + * @author 芋艿 + */ +@Mapper +public interface PayAppConvert { + + PayAppConvert INSTANCE = Mappers.getMapper(PayAppConvert.class); + + PayAppPageItemRespVO pageConvert (PayAppDO bean); + + PayAppPageItemRespVO.PayMerchant convert(PayMerchantDO bean); + + PayAppDO convert(PayAppCreateReqVO bean); + + PayAppDO convert(PayAppUpdateReqVO bean); + + PayAppRespVO convert(PayAppDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/channel/PayChannelConvert.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/channel/PayChannelConvert.java new file mode 100644 index 0000000..2535008 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/channel/PayChannelConvert.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.pay.convert.channel; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelExcelVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelRespVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelUpdateReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface PayChannelConvert { + + PayChannelConvert INSTANCE = Mappers.getMapper(PayChannelConvert.class); + + @Mapping(target = "config",ignore = true) + PayChannelDO convert(PayChannelCreateReqVO bean); + + @Mapping(target = "config",ignore = true) + PayChannelDO convert(PayChannelUpdateReqVO bean); + + @Mapping(target = "config",expression = "java(cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString(bean.getConfig()))") + PayChannelRespVO convert(PayChannelDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + + + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/merchant/PayMerchantConvert.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/merchant/PayMerchantConvert.java new file mode 100644 index 0000000..1cb51a2 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/merchant/PayMerchantConvert.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.pay.convert.merchant; + +import java.util.*; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; + +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantExcelVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantRespVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantUpdateReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface PayMerchantConvert { + + PayMerchantConvert INSTANCE = Mappers.getMapper(PayMerchantConvert.class); + + PayMerchantDO convert(PayMerchantCreateReqVO bean); + + PayMerchantDO convert(PayMerchantUpdateReqVO bean); + + PayMerchantRespVO convert(PayMerchantDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java new file mode 100755 index 0000000..49df1ea --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/order/PayOrderConvert.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.pay.convert.order; + +import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderDetailsRespVO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExcelVO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageItemRespVO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; + +/** + * 支付订单 Convert + * + * @author aquan + */ +@Mapper +public interface PayOrderConvert { + + PayOrderConvert INSTANCE = Mappers.getMapper(PayOrderConvert.class); + + PayOrderRespVO convert(PayOrderDO bean); + + PayOrderDetailsRespVO orderDetailConvert(PayOrderDO bean); + + PayOrderDetailsRespVO.PayOrderExtension orderDetailExtensionConvert(PayOrderExtensionDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + + /** + * 订单DO转自定义分页对象 + * + * @param bean 订单DO + * @return 分页对象 + */ + PayOrderPageItemRespVO pageConvertItemPage(PayOrderDO bean); + + default PayOrderExcelVO excelConvert(PayOrderDO bean) { + if (bean == null) { + return null; + } + + PayOrderExcelVO payOrderExcelVO = new PayOrderExcelVO(); + + payOrderExcelVO.setId(bean.getId()); + payOrderExcelVO.setSubject(bean.getSubject()); + payOrderExcelVO.setMerchantOrderId(bean.getMerchantOrderId()); + payOrderExcelVO.setChannelOrderNo(bean.getChannelOrderNo()); + payOrderExcelVO.setStatus(bean.getStatus()); + payOrderExcelVO.setNotifyStatus(bean.getNotifyStatus()); + payOrderExcelVO.setNotifyUrl(bean.getNotifyUrl()); + payOrderExcelVO.setCreateTime(bean.getCreateTime()); + payOrderExcelVO.setSuccessTime(bean.getSuccessTime()); + payOrderExcelVO.setExpireTime(bean.getExpireTime()); + payOrderExcelVO.setNotifyTime(bean.getNotifyTime()); + payOrderExcelVO.setUserIp(bean.getUserIp()); + payOrderExcelVO.setRefundStatus(bean.getRefundStatus()); + payOrderExcelVO.setRefundTimes(bean.getRefundTimes()); + payOrderExcelVO.setBody(bean.getBody()); + + BigDecimal multiple = new BigDecimal(100); + + payOrderExcelVO.setAmount(BigDecimal.valueOf(bean.getAmount()) + .divide(multiple, 2, RoundingMode.HALF_UP).toString()); + + payOrderExcelVO.setChannelFeeAmount(BigDecimal.valueOf(bean.getChannelFeeAmount()) + .divide(multiple, 2, RoundingMode.HALF_UP).toString()); + payOrderExcelVO.setChannelFeeRate(java.math.BigDecimal.valueOf(bean.getChannelFeeRate()) + .multiply(multiple).toString()); + payOrderExcelVO.setRefundAmount(BigDecimal.valueOf(bean.getRefundAmount()) + .divide(multiple, 2, RoundingMode.HALF_UP).toString()); + + return payOrderExcelVO; + } + + + PayOrderDO convert(PayOrderCreateReqDTO bean); + + PayOrderExtensionDO convert(PayOrderSubmitReqDTO bean); + + PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqDTO bean); + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/package-info.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/package-info.java new file mode 100644 index 0000000..df43d5a --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/package-info.java @@ -0,0 +1,6 @@ +/** + * 提供 POJO 类的实体转换 + * + * 目前使用 MapStruct 框架 + */ +package cn.iocoder.yudao.module.pay.convert; diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java new file mode 100755 index 0000000..2e034c6 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/refund/PayRefundConvert.java @@ -0,0 +1,109 @@ +package cn.iocoder.yudao.module.pay.convert.refund; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.*; +import cn.iocoder.yudao.module.pay.controller.app.refund.vo.AppPayRefundReqVO; +import cn.iocoder.yudao.module.pay.controller.app.refund.vo.AppPayRefundRespVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayRefundReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayRefundRespDTO; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; + +/** + * 退款订单 Convert + * + * @author aquan + */ +@Mapper +public interface PayRefundConvert { + + PayRefundConvert INSTANCE = Mappers.getMapper(PayRefundConvert.class); + + PayRefundDO convert(PayRefundCreateReqVO bean); + + PayRefundDO convert(PayRefundUpdateReqVO bean); + + PayRefundRespVO convert(PayRefundDO bean); + + /** + * 退款订单 DO 转 退款详情订单 VO + * + * @param bean 退款订单 DO + * @return 退款详情订单 VO + */ + PayRefundDetailsRespVO refundDetailConvert(PayRefundDO bean); + + /** + * 退款订单DO 转 分页退款条目VO + * + * @param bean 退款订单DO + * @return 分页退款条目VO + */ + PayRefundPageItemRespVO pageItemConvert(PayRefundDO bean); + + List convertList(List list); + + PageResult convertPage(PageResult page); + + List convertList02(List list); + + /** + * 退款订单DO 转 导出excel VO + * + * @param bean 退款订单DO + * @return 导出 excel VO + */ + default PayRefundExcelVO excelConvert(PayRefundDO bean) { + if (bean == null) { + return null; + } + + PayRefundExcelVO payRefundExcelVO = new PayRefundExcelVO(); + + payRefundExcelVO.setId(bean.getId()); + payRefundExcelVO.setTradeNo(bean.getTradeNo()); + payRefundExcelVO.setMerchantOrderId(bean.getMerchantOrderId()); + payRefundExcelVO.setMerchantRefundNo(bean.getMerchantRefundNo()); + payRefundExcelVO.setNotifyUrl(bean.getNotifyUrl()); + payRefundExcelVO.setNotifyStatus(bean.getNotifyStatus()); + payRefundExcelVO.setStatus(bean.getStatus()); + payRefundExcelVO.setType(bean.getType()); + payRefundExcelVO.setReason(bean.getReason()); + payRefundExcelVO.setUserIp(bean.getUserIp()); + payRefundExcelVO.setChannelOrderNo(bean.getChannelOrderNo()); + payRefundExcelVO.setChannelRefundNo(bean.getChannelRefundNo()); + payRefundExcelVO.setExpireTime(bean.getExpireTime()); + payRefundExcelVO.setSuccessTime(bean.getSuccessTime()); + payRefundExcelVO.setNotifyTime(bean.getNotifyTime()); + payRefundExcelVO.setCreateTime(bean.getCreateTime()); + + BigDecimal multiple = new BigDecimal(100); + payRefundExcelVO.setPayAmount(BigDecimal.valueOf(bean.getPayAmount()) + .divide(multiple, 2, RoundingMode.HALF_UP).toString()); + payRefundExcelVO.setRefundAmount(BigDecimal.valueOf(bean.getRefundAmount()) + .divide(multiple, 2, RoundingMode.HALF_UP).toString()); + + return payRefundExcelVO; + } + + //TODO 太多需要处理了, 暂时不用 + @Mappings(value = { + @Mapping(source = "amount", target = "payAmount"), + @Mapping(source = "id", target = "orderId"), + @Mapping(target = "status",ignore = true) + }) + PayRefundDO convert(PayOrderDO orderDO); + + PayRefundReqDTO convert(AppPayRefundReqVO bean); + + AppPayRefundRespVO convert(PayRefundRespDTO bean); + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md new file mode 100644 index 0000000..8153487 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md @@ -0,0 +1 @@ + diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayAppDO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayAppDO.java new file mode 100644 index 0000000..371a92b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayAppDO.java @@ -0,0 +1,62 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.merchant; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 支付应用 DO + * 一个商户下,可能会有多个支付应用。例如说,京东有京东商城、京东到家等等 + * 不过一般来说,一个商户,只有一个应用哈~ + * + * 即 PayMerchantDO : PayAppDO = 1 : n + * + * @author 芋道源码 + */ +@TableName("pay_app") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayAppDO extends BaseDO { + + /** + * 应用编号,数据库自增 + */ + @TableId + private Long id; + /** + * 应用名 + */ + private String name; + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String remark; + /** + * 支付结果的回调地址 + */ + private String payNotifyUrl; + /** + * 退款结果的回调地址 + */ + private String refundNotifyUrl; + + /** + * 商户编号 + * + * 关联 {@link PayMerchantDO#getId()} + */ + private Long merchantId; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayChannelDO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayChannelDO.java new file mode 100644 index 0000000..a670db4 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayChannelDO.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.merchant; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.*; + +/** + * 支付渠道 DO + * 一个应用下,会有多种支付渠道,例如说微信支付、支付宝支付等等 + * + * 即 PayAppDO : PayChannelDO = 1 : n + * + * @author 芋道源码 + */ +@Data +@TableName(value = "pay_channel", autoResultMap = true) +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayChannelDO extends BaseDO { + + /** + * 渠道编号,数据库自增 + */ + private Long id; + /** + * 渠道编码 + * + * 枚举 {@link PayChannelEnum} + */ + private String code; + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + /** + * 渠道费率,单位:百分比 + */ + private Double feeRate; + /** + * 备注 + */ + private String remark; + + /** + * 商户编号 + * + * 关联 {@link PayMerchantDO#getId()} + */ + private Long merchantId; + /** + * 应用编号 + * + * 关联 {@link PayAppDO#getId()} + */ + private Long appId; + /** + * 支付渠道配置 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private PayClientConfig config; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayMerchantDO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayMerchantDO.java new file mode 100644 index 0000000..ebd735b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/merchant/PayMerchantDO.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.merchant; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 支付商户信息 DO + * 目前暂时没有特别的用途,主要为未来多商户提供基础。 + * + * @author 芋道源码 + */ +@Data +@TableName("pay_merchant") +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayMerchantDO extends BaseDO { + + /** + * 商户编号,数据库自增 + */ + @TableId + private Long id; + /** + * 商户号 + * 例如说,M233666999 + * 只有新增时插入,不允许修改 + */ + private String no; + /** + * 商户全称 + */ + private String name; + /** + * 商户简称 + */ + private String shortName; + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyLogDO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyLogDO.java new file mode 100644 index 0000000..92ecc39 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyLogDO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.notify; + +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 商户支付、退款等的通知 Log + * 每次通知时,都会在该表中,记录一次 Log,方便排查问题 + * + * @author 芋道源码 + */ +@TableName("pay_notify_log") +@Data +@EqualsAndHashCode(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayNotifyLogDO extends BaseDO { + + /** + * 日志编号,自增 + */ + private Long id; + /** + * 通知任务编号 + * + * 关联 {@link PayNotifyTaskDO#getId()} + */ + private Long taskId; + /** + * 第几次被通知 + * + * 对应到 {@link PayNotifyTaskDO#getNotifyTimes()} + */ + private Integer notifyTimes; + /** + * HTTP 响应结果 + */ + private String response; + /** + * 支付通知状态 + * + * 外键 {@link PayNotifyStatusEnum} + */ + private Integer status; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java new file mode 100644 index 0000000..3884f15 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/notify/PayNotifyTaskDO.java @@ -0,0 +1,99 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.notify; + +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.util.Date; + +/** + * 商户支付、退款等的通知 + * 在支付系统收到支付渠道的支付、退款的结果后,需要不断的通知到业务系统,直到成功。 + * + * @author 芋道源码 + */ +@TableName("pay_notify_task") +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +public class PayNotifyTaskDO extends BaseDO { + + /** + * 通知频率,单位为秒。 + * + * 算上首次的通知,实际是一共 1 + 8 = 9 次。 + */ + public static final Integer[] NOTIFY_FREQUENCY = new Integer[]{ + 15, 15, 30, 180, + 1800, 1800, 1800, 3600 + }; + + /** + * 编号,自增 + */ + private Long id; + /** + * 商户编号 + * + * 关联 {@link PayMerchantDO#getId()} + */ + private Long merchantId; + /** + * 应用编号 + * + * 关联 {@link PayAppDO#getId()} + */ + private Long appId; + /** + * 通知类型 + * + * 外键 {@link PayNotifyTypeEnum} + */ + private Integer type; + /** + * 数据编号,根据不同 type 进行关联: + * + * 1. {@link PayNotifyTypeEnum#ORDER} 时,关联 {@link PayOrderDO#getId()} + * 2. {@link PayNotifyTypeEnum#REFUND} 时,关联 {@link PayRefundDO#getId()} + */ + private Long dataId; + /** + * 商户订单编号 + */ + private String merchantOrderId; + /** + * 通知状态 + * + * 外键 {@link PayNotifyStatusEnum} + */ + private Integer status; + /** + * 下一次通知时间 + */ + private Date nextNotifyTime; + /** + * 最后一次执行时间 + */ + private Date lastExecuteTime; + /** + * 当前通知次数 + */ + private Integer notifyTimes; + /** + * 最大可通知次数 + */ + private Integer maxNotifyTimes; + /** + * 通知地址 + */ + private String notifyUrl; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java new file mode 100644 index 0000000..931b856 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderDO.java @@ -0,0 +1,162 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.order; + +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundTypeEnum; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.util.Date; + +/** + * 支付订单 DO + * + * @author 芋道源码 + */ +@TableName("pay_order") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayOrderDO extends BaseDO { + + /** + * 订单编号,数据库自增 + */ + private Long id; + /** + * 商户编号 + * + * 关联 {@link PayMerchantDO#getId()} + */ + private Long merchantId; + /** + * 应用编号 + * + * 关联 {@link PayAppDO#getId()} + */ + private Long appId; + /** + * 渠道编号 + * + * 关联 {@link PayChannelDO#getId()} + */ + private Long channelId; + /** + * 渠道编码 + * + * 枚举 {@link PayChannelEnum} + */ + private String channelCode; + + // ========== 商户相关字段 ========== + + /** + * 商户订单编号 + * 例如说,内部系统 A 的订单号。需要保证每个 PayMerchantDO 唯一 + */ + private String merchantOrderId; + /** + * 商品标题 + */ + private String subject; + /** + * 商品描述信息 + */ + private String body; + /** + * 异步通知地址 + */ + private String notifyUrl; + /** + * 通知商户支付结果的回调状态 + * + * 枚举 {@link PayOrderNotifyStatusEnum} + */ + private Integer notifyStatus; +// /** +// * 商户拓展参数 +// */ +// private Map merchantExtras; + + // ========== 订单相关字段 ========== + + /** + * 支付金额,单位:分 + */ + private Long amount; + /** + * 渠道手续费,单位:百分比 + * + * 冗余 {@link PayChannelDO#getFeeRate()} + */ + private Double channelFeeRate; + /** + * 渠道手续金额,单位:分 + */ + private Long channelFeeAmount; + /** + * 支付状态 + * + * 枚举 {@link PayOrderStatusEnum} + */ + private Integer status; + /** + * 用户 IP + */ + private String userIp; + /** + * 订单失效时间 + */ + private Date expireTime; + /** + * 订单支付成功时间 + */ + private Date successTime; + /** + * 订单支付通知时间,即支付渠道的通知时间 + */ + private Date notifyTime; + /** + * 支付成功的订单拓展单编号 + * + * 关联 {@link PayOrderDO#getId()} + */ + private Long successExtensionId; + + // ========== 退款相关字段 ========== + /** + * 退款状态 + * + * 枚举 {@link PayRefundTypeEnum} + */ + private Integer refundStatus; + /** + * 退款次数 + */ + private Integer refundTimes; + /** + * 退款总金额,单位:分 + */ + private Long refundAmount; + + // ========== 渠道相关字段 ========== + /** + * 渠道用户编号 + * + * 例如说,微信 openid、支付宝账号 + */ + private String channelUserId; + /** + * 渠道订单号 + */ + private String channelOrderNo; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderExtensionDO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderExtensionDO.java new file mode 100644 index 0000000..8606e08 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/order/PayOrderExtensionDO.java @@ -0,0 +1,82 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.order; + +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.*; + +import java.util.Map; + +/** + * 支付订单拓展 DO + * + * + * @author 芋道源码 + */ +@TableName(value = "pay_order_extension",autoResultMap = true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayOrderExtensionDO extends BaseDO { + + /** + * 订单拓展编号,数据库自增 + */ + private Long id; + /** + * 支付订单号,根据规则生成 + * 调用支付渠道时,使用该字段作为对接的订单号。 + * 1. 调用微信支付 https://api.mch.weixin.qq.com/pay/unifiedorder 时,使用该字段作为 out_trade_no + * 2. 调用支付宝 https://opendocs.alipay.com/apis 时,使用该字段作为 out_trade_no + * + * 例如说,P202110132239124200055 + */ + private String no; + /** + * 订单号 + * + * 关联 {@link PayOrderDO#getId()} + */ + private Long orderId; + /** + * 渠道编号 + * + * 关联 {@link PayChannelDO#getId()} + */ + private Long channelId; + /** + * 渠道编码 + */ + private String channelCode; + /** + * 用户 IP + */ + private String userIp; + /** + * 支付状态 + * + * 枚举 {@link PayOrderStatusEnum} + * 注意,只包含上述枚举的 WAITING 和 SUCCESS + */ + private Integer status; + /** + * 支付渠道的额外参数 + * + * 参见 https://www.pingxx.com/api/支付渠道%20extra%20参数说明.html + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private Map channelExtras; + /** + * 支付渠道异步通知的内容 + * + * 在支持成功后,会记录回调的数据 + */ + private String channelNotifyData; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java new file mode 100644 index 0000000..f5e3a1f --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java @@ -0,0 +1,197 @@ +package cn.iocoder.yudao.module.pay.dal.dataobject.refund; + +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundTypeEnum; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.util.Date; + +/** + * 支付退款单 DO + * 一个支付订单,可以拥有多个支付退款单 + * + * 即 PayOrderDO : PayRefundDO = 1 : n + * + * @author 芋道源码 + */ +@TableName("pay_refund") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayRefundDO extends BaseDO { + + /** + * 退款单编号,数据库自增 + */ + @TableId + private Long id; + + /** + * 商户编号 + * + * 关联 {@link PayMerchantDO#getId()} + */ + private Long merchantId; + /** + * 应用编号 + * + * 关联 {@link PayAppDO#getId()} + */ + private Long appId; + /** + * 渠道编号 + * + * 关联 {@link PayChannelDO#getId()} + */ + private Long channelId; + /** + * 商户编码 + * + * 枚举 {@link PayChannelEnum} + */ + private String channelCode; + /** + * 订单编号 + * + * 关联 {@link PayOrderDO#getId()} + */ + private Long orderId; + + /** + * 交易订单号,根据规则生成 + * 调用支付渠道时,使用该字段作为对接的订单号。 + * 1. 调用微信支付 https://api.mch.weixin.qq.com/v3/refund/domestic/refunds 时,使用该字段作为 out_trade_no + * 2. 调用支付宝 https://opendocs.alipay.com/apis 时,使用该字段作为 out_trade_no + * 这里对应 pay_extension 里面的 no + * 例如说,P202110132239124200055 + */ + private String tradeNo; + + + // ========== 商户相关字段 ========== + /** + * 商户订单编号 + */ + private String merchantOrderId; + + /** + * 商户退款订单号, 由商户系统产生, 由他们保证唯一,不能为空,通知商户时会传该字段。 + * 例如说,内部系统 A 的退款订单号。需要保证每个 PayMerchantDO 唯一 + * 个商户退款订单,对应一条退款请求记录。可多次提交。 渠道保持幂等 + * 使用商户退款单,作为退款请求号 + * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_9.shtml 中的 out_refund_no + * https://opendocs.alipay.com/apis alipay.trade.refund 中的 out_request_no + * 退款请求号。 + * 标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。 + * 注:针对同一次退款请求,如果调用接口失败或异常了,重试时需要保证退款请求号不能变更, + * 防止该笔交易重复退款。支付宝会保证同样的退款请求号多次请求只会退一次。 + * 退款单请求号,根据规则生成 + * 例如说,R202109181134287570000 + */ + // TODO @jason:merchantRefundNo =》merchantRefundOId + private String merchantRefundNo; + + /** + * 异步通知地址 + */ + private String notifyUrl; + + /** + * 通知商户退款结果的回调状态 + * TODO 0 未发送 1 已发送 + */ + private Integer notifyStatus; + + // ========== 退款相关字段 ========== + /** + * 退款状态 + * + * 枚举 {@link PayRefundStatusEnum} + */ + private Integer status; + + /** + * 退款类型(部分退款,全部退款) + * + * 枚举 {@link PayRefundTypeEnum} + */ + private Integer type; + /** + * 支付金额,单位:分 + */ + private Long payAmount; + /** + * 退款金额,单位:分 + */ + private Long refundAmount; + + /** + * 退款原因 + */ + private String reason; + + /** + * 用户 IP + */ + private String userIp; + + // ========== 渠道相关字段 ========== + /** + * 渠道订单号,pay_order 中的channel_order_no 对应 + */ + private String channelOrderNo; + /** + * 微信中的 refund_id + * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_9.shtml + * 支付宝没有 + * 渠道退款单号,渠道返回 + */ + private String channelRefundNo; + + /** + * 调用渠道的错误码 + */ + private String channelErrorCode; + + /** + * 调用渠道报错时,错误信息 + */ + private String channelErrorMsg; + + + /** + * 支付渠道的额外参数 + * 参见 https://www.pingxx.com/api/Refunds%20退款概述.html + */ + private String channelExtras; + + + /** + * TODO + * 退款失效时间 + */ + private Date expireTime; + /** + * 退款成功时间 + */ + private Date successTime; + /** + * 退款通知时间 + */ + private Date notifyTime; + + + + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayAppMapper.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayAppMapper.java new file mode 100644 index 0000000..03cb043 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayAppMapper.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.merchant; + +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppPageReqVO; +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.merchant.PayAppDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +@Mapper +public interface PayAppMapper extends BaseMapperX { + + default PageResult selectPage(PayAppPageReqVO reqVO, Collection merchantIds) { + 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()) + .inIfPresent("merchant_id", merchantIds) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); + } + + default List selectList(PayAppExportReqVO reqVO, Collection merchantIds) { + return selectList(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()) + .inIfPresent("merchant_id", merchantIds) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); + } + + default List getListByMerchantId(String merchantId) { + return selectList(new LambdaQueryWrapper() + .select(PayAppDO::getId, PayAppDO::getName) + .eq(PayAppDO::getMerchantId, merchantId)); + } + + // TODO @aquan:方法名补充 ByMerchantId + default Long selectCount(Long merchantId) { + return selectCount(new LambdaQueryWrapper().eq(PayAppDO::getMerchantId, merchantId)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapper.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapper.java new file mode 100644 index 0000000..c187153 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayChannelMapper.java @@ -0,0 +1,96 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.merchant; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelPageReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.Collection; +import java.util.Date; +import java.util.List; + +@Mapper +public interface PayChannelMapper extends BaseMapperX { + + default PayChannelDO selectByAppIdAndCode(Long appId, String code) { + return selectOne(PayChannelDO::getAppId, appId, PayChannelDO::getCode, code); + } + + @Select("SELECT id FROM pay_channel WHERE update_time > #{maxUpdateTime} LIMIT 1") + Long selectExistsByUpdateTimeAfter(Date maxUpdateTime); + + default PageResult selectPage(PayChannelPageReqVO reqVO) { + return selectPage(reqVO, new QueryWrapperX() + .eqIfPresent("code", reqVO.getCode()) + .eqIfPresent("status", reqVO.getStatus()) + .eqIfPresent("remark", reqVO.getRemark()) + .eqIfPresent("fee_rate", reqVO.getFeeRate()) + .eqIfPresent("merchant_id", reqVO.getMerchantId()) + .eqIfPresent("app_id", reqVO.getAppId()) + // .eqIfPresent("config", reqVO.getConfig()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id") ); + } + + default List selectList(PayChannelExportReqVO reqVO) { + return selectList(new QueryWrapperX() + .eqIfPresent("code", reqVO.getCode()) + .eqIfPresent("status", reqVO.getStatus()) + .eqIfPresent("remark", reqVO.getRemark()) + .eqIfPresent("fee_rate", reqVO.getFeeRate()) + .eqIfPresent("merchant_id", reqVO.getMerchantId()) + .eqIfPresent("app_id", reqVO.getAppId()) + // .eqIfPresent("config", reqVO.getConfig()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id") ); + } + + /** + * 根据条件获取渠道数量 + * + * @param merchantId 商户编号 + * @param appid 应用编号 + * @param code 渠道编码 + * @return 数量 + */ + default Integer selectCount(Long merchantId, Long appid, String code) { + return this.selectCount(new QueryWrapper().lambda() + .eq(PayChannelDO::getMerchantId, merchantId) + .eq(PayChannelDO::getAppId, appid) + .eq(PayChannelDO::getCode, code)).intValue(); + } + + /** + * 根据条件获取渠道 + * + * @param merchantId 商户编号 + * @param appid 应用编号 // TODO @aquan:appid =》appId + * @param code 渠道编码 + * @return 数量 + */ + default PayChannelDO selectOne(Long merchantId, Long appid, String code) { + return this.selectOne((new QueryWrapper().lambda() + .eq(PayChannelDO::getMerchantId, merchantId) + .eq(PayChannelDO::getAppId, appid) + .eq(PayChannelDO::getCode, code) + )); + } + + // TODO @aquan:select 命名 + /** + * 根据支付应用ID集合获得支付渠道列表 + * + * @param appIds 应用编号集合 + * @return 支付渠道列表 + */ + default List getChannelListByAppIds(Collection appIds){ + return this.selectList(new QueryWrapper().lambda() + .in(PayChannelDO::getAppId, appIds)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayMerchantMapper.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayMerchantMapper.java new file mode 100644 index 0000000..050302b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/merchant/PayMerchantMapper.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.merchant; + +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantPageReqVO; +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.merchant.PayMerchantDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface PayMerchantMapper extends BaseMapperX { + + default PageResult selectPage(PayMerchantPageReqVO reqVO) { + return selectPage(reqVO, new QueryWrapperX() + .likeIfPresent("no", reqVO.getNo()) + .likeIfPresent("name", reqVO.getName()) + .likeIfPresent("short_name", reqVO.getShortName()) + .eqIfPresent("status", reqVO.getStatus()) + .eqIfPresent("remark", reqVO.getRemark()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); + } + + default List selectList(PayMerchantExportReqVO reqVO) { + return selectList(new QueryWrapperX() + .likeIfPresent("no", reqVO.getNo()) + .likeIfPresent("name", reqVO.getName()) + .likeIfPresent("short_name", reqVO.getShortName()) + .eqIfPresent("status", reqVO.getStatus()) + .eqIfPresent("remark", reqVO.getRemark()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); + } + + /** + * 根据商户名称模糊查询商户集合 + * + * @param merchantName 商户名称 + * @return 商户集合 + */ + default List getMerchantListByName(String merchantName) { + return this.selectList(new QueryWrapperX() + .likeIfPresent("name", merchantName)); + } +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java new file mode 100644 index 0000000..c956219 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyLogCoreMapper.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.notify; + +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PayNotifyLogCoreMapper extends BaseMapperX { +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java new file mode 100644 index 0000000..1107a19 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/notify/PayNotifyTaskCoreMapper.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.notify; + +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Date; +import java.util.List; + +@Mapper +public interface PayNotifyTaskCoreMapper extends BaseMapperX { + + /** + * 获得需要通知的 PayNotifyTaskDO 记录。需要满足如下条件: + * + * 1. status 非成功 + * 2. nextNotifyTime 小于当前时间 + * + * @return PayTransactionNotifyTaskDO 数组 + */ + default List selectListByNotify() { + return selectList(new QueryWrapper() + .in("status", PayNotifyStatusEnum.WAITING.getStatus(), PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus(), + PayNotifyStatusEnum.REQUEST_FAILURE.getStatus()) + .le("next_notify_time", new Date())); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java new file mode 100755 index 0000000..a8918f4 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.order; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface PayOrderExtensionMapper extends BaseMapperX { + + default PayOrderExtensionDO selectByNo(String no) { + return selectOne(PayOrderExtensionDO::getNo, no); + } + + default int updateByIdAndStatus(Long id, Integer status, PayOrderExtensionDO update) { + return update(update, new LambdaQueryWrapper() + .eq(PayOrderExtensionDO::getId, id).eq(PayOrderExtensionDO::getStatus, status)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java new file mode 100755 index 0000000..4ff345d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderMapper.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.order; + +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO; +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.order.PayOrderDO; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import org.apache.ibatis.annotations.Mapper; + +import java.util.Collection; +import java.util.List; + +@Mapper +public interface PayOrderMapper extends BaseMapperX { + + default PageResult selectPage(PayOrderPageReqVO reqVO) { + return selectPage(reqVO, new QueryWrapperX() + .eqIfPresent("merchant_id", reqVO.getMerchantId()) + .eqIfPresent("app_id", reqVO.getAppId()) + .eqIfPresent("channel_id", reqVO.getChannelId()) + .eqIfPresent("channel_code", reqVO.getChannelCode()) + .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId()) + .eqIfPresent("notify_status", reqVO.getNotifyStatus()) + .eqIfPresent("status", reqVO.getStatus()) + .eqIfPresent("refund_status", reqVO.getRefundStatus()) + .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); + } + + default List selectList(PayOrderExportReqVO reqVO) { + return selectList(new QueryWrapperX() + .eqIfPresent("merchant_id", reqVO.getMerchantId()) + .eqIfPresent("app_id", reqVO.getAppId()) + .eqIfPresent("channel_id", reqVO.getChannelId()) + .eqIfPresent("channel_code", reqVO.getChannelCode()) + .likeIfPresent("merchant_order_id", reqVO.getMerchantOrderId()) + .eqIfPresent("notify_status", reqVO.getNotifyStatus()) + .eqIfPresent("status", reqVO.getStatus()) + .eqIfPresent("refund_status", reqVO.getRefundStatus()) + .likeIfPresent("channel_order_no", reqVO.getChannelOrderNo()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); + } + + default List findByIdListQueryOrderSubject(Collection idList) { + return selectList(new LambdaQueryWrapper() + .select(PayOrderDO::getId, PayOrderDO::getSubject) + .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 PayOrderDO selectByAppIdAndMerchantOrderId(Long appId, String merchantOrderId) { + return selectOne(new QueryWrapper().eq("app_id", appId) + .eq("merchant_order_id", merchantOrderId)); + } + + default int updateByIdAndStatus(Long id, Integer status, PayOrderDO update) { + return update(update, new QueryWrapper() + .eq("id", id).eq("status", status)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java new file mode 100755 index 0000000..ba8f521 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.pay.dal.mysql.refund; + +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO; +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; + +@Mapper +public interface PayRefundMapper extends BaseMapperX { + + default PageResult selectPage(PayRefundPageReqVO reqVO) { + return selectPage(reqVO, new QueryWrapperX() + .eqIfPresent("merchant_id", reqVO.getMerchantId()) + .eqIfPresent("app_id", reqVO.getAppId()) + .eqIfPresent("channel_code", reqVO.getChannelCode()) + .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo()) + .eqIfPresent("type", reqVO.getType()) + .eqIfPresent("status", reqVO.getStatus()) + .eqIfPresent("notify_status", reqVO.getNotifyStatus()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); + } + + default List selectList(PayRefundExportReqVO reqVO) { + return selectList(new QueryWrapperX() + .eqIfPresent("merchant_id", reqVO.getMerchantId()) + .eqIfPresent("app_id", reqVO.getAppId()) + .eqIfPresent("channel_code", reqVO.getChannelCode()) + .likeIfPresent("merchant_refund_no", reqVO.getMerchantRefundNo()) + .eqIfPresent("type", reqVO.getType()) + .eqIfPresent("status", reqVO.getStatus()) + .eqIfPresent("notify_status", reqVO.getNotifyStatus()) + .betweenIfPresent("create_time", reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) + .orderByDesc("id")); + } + + default Long selectCount(Long appId, Integer status) { + + return selectCount(new LambdaQueryWrapper() + .eq(PayRefundDO::getAppId, appId) + .eq(PayRefundDO::getStatus, status)); + } + + default PayRefundDO selectByReqNo(String reqNo) { + return selectOne("req_no", reqNo); + } + + 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-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/PayRedisKeyCoreConstants.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/PayRedisKeyCoreConstants.java new file mode 100644 index 0000000..acba20b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/PayRedisKeyCoreConstants.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.pay.dal.redis; + +import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; +import org.redisson.api.RLock; + +import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.HASH; + +/** + * 支付 Redis Key 枚举类 + * + * @author 芋道源码 + */ +public interface PayRedisKeyCoreConstants { + + RedisKeyDefine PAY_NOTIFY_LOCK = new RedisKeyDefine("通知任务的分布式锁", + "pay_notify:lock:", // 参数来自 DefaultLockKeyBuilder 类 + RedisKeyDefine.KeyTypeEnum.HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构 + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/notify/PayNotifyLockRedisDAO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/notify/PayNotifyLockRedisDAO.java new file mode 100644 index 0000000..227eda2 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/notify/PayNotifyLockRedisDAO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.pay.dal.redis.notify; + +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.stereotype.Repository; + +import javax.annotation.Resource; +import java.util.concurrent.TimeUnit; + +import static cn.iocoder.yudao.module.pay.dal.redis.PayRedisKeyCoreConstants.PAY_NOTIFY_LOCK; + +/** + * 支付通知的锁 Redis DAO + * + * @author 芋道源码 + */ +@Repository +public class PayNotifyLockRedisDAO { + + @Resource + private RedissonClient redissonClient; + + public void lock(Long id, Long timeoutMillis, Runnable runnable) { + String lockKey = formatKey(id); + RLock lock = redissonClient.getLock(lockKey); + try { + lock.lock(timeoutMillis, TimeUnit.MILLISECONDS); + // 执行逻辑 + runnable.run(); + } finally { + lock.unlock(); + } + } + + private static String formatKey(Long id) { + return String.format(PAY_NOTIFY_LOCK.getKeyTemplate(), id); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java new file mode 100644 index 0000000..d1b7c10 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyStatusEnum.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.pay.enums.notify; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 支付通知状态枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PayNotifyStatusEnum { + + WAITING(1, "等待通知"), + SUCCESS(2, "通知成功"), + FAILURE(3, "通知失败"), // 多次尝试,彻底失败 + REQUEST_SUCCESS(4, "请求成功,但是结果失败"), + REQUEST_FAILURE(5, "请求失败"), + + ; + + /** + * 状态 + */ + private final Integer status; + /** + * 名字 + */ + private final String name; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java new file mode 100644 index 0000000..8c259d9 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/notify/PayNotifyTypeEnum.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.pay.enums.notify; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 支付通知类型 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PayNotifyTypeEnum { + + ORDER(1, "支付单"), + REFUND(2, "退款单"), + ; + + /** + * 类型 + */ + private final Integer type; + /** + * 名字 + */ + private final String name; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderNotifyStatusEnum.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderNotifyStatusEnum.java new file mode 100644 index 0000000..b7161a9 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderNotifyStatusEnum.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.pay.enums.order; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 支付订单的通知状态枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PayOrderNotifyStatusEnum implements IntArrayValuable { + + NO(0, "未通知"), + SUCCESS(10, "通知成功"), + FAILURE(20, "通知失败") + ; + + private final Integer status; + private final String name; + + @Override + public int[] array() { + return new int[0]; + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderStatusEnum.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderStatusEnum.java new file mode 100644 index 0000000..ab542a9 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderStatusEnum.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.pay.enums.order; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 支付订单的状态枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PayOrderStatusEnum implements IntArrayValuable { + + WAITING(0, "未支付"), + SUCCESS(10, "支付成功"), + CLOSED(20, "支付关闭"), // 未付款交易超时关闭,或支付完成后全额退款 TODO 芋艿:需要优化下 + ; + + private final Integer status; + private final String name; + + @Override + public int[] array() { + return new int[0]; + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundStatusEnum.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundStatusEnum.java new file mode 100644 index 0000000..390804d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundStatusEnum.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.pay.enums.refund; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum PayRefundStatusEnum { + + CREATE(0, "退款订单生成"), + SUCCESS(1, "退款成功"), + FAILURE(2, "退款失败"), + CLOSE(99, "退款关闭"); + + private final Integer status; + private final String name; +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundTypeEnum.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundTypeEnum.java new file mode 100644 index 0000000..5fb10a3 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/enums/refund/PayRefundTypeEnum.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.pay.enums.refund; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 支付订单的退款状态枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PayRefundTypeEnum implements IntArrayValuable { + + NO(0, "未退款"), + SOME(10, "部分退款"), + ALL(20, "全部退款") + ; + + private final Integer status; + private final String name; + + @Override + public int[] array() { + return new int[0]; + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java new file mode 100644 index 0000000..820bca4 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.pay.job.notify; + +import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; +import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 支付通知 Job + * 通过不断扫描待通知的 PayNotifyTaskDO 记录,回调业务线的回调接口 + * + * @author 芋道源码 + */ +@Component +@Slf4j +public class PayNotifyJob implements JobHandler { + + @Resource + private PayNotifyService payNotifyCoreService; + + @Override + public String execute(String param) throws Exception { + int notifyCount = payNotifyCoreService.executeNotify(); + return String.format("执行支付通知 %s 个", notifyCount); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/package-info.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/package-info.java new file mode 100644 index 0000000..c45bf49 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/job/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.pay.job; diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/package-info.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/package-info.java new file mode 100644 index 0000000..1421e4e --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/package-info.java @@ -0,0 +1,10 @@ +/** + * pay 模块,我们放支付业务,提供业务的支付能力。 + * 例如说:商户、应用、支付、退款等等 + * + * 1. Controller URL:以 /member/ 开头,避免和其它 Module 冲突 + * 2. DataObject 表名:以 member_ 开头,方便在数据库中区分 + * + * 注意,由于 Pay 模块和 Trade 模块,容易重名,所以类名都加载 Pay 的前缀~ + */ +package cn.iocoder.yudao.module.pay; diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppService.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppService.java new file mode 100644 index 0000000..62935e4 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppService.java @@ -0,0 +1,116 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppUpdateReqVO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 支付应用信息 Service 接口 + * + * @author 芋艿 + */ +public interface PayAppService { + + /** + * 创建支付应用信息 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createApp(@Valid PayAppCreateReqVO createReqVO); + + /** + * 更新支付应用信息 + * + * @param updateReqVO 更新信息 + */ + void updateApp(@Valid PayAppUpdateReqVO updateReqVO); + + /** + * 删除支付应用信息 + * + * @param id 编号 + */ + void deleteApp(Long id); + + /** + * 获得支付应用信息 + * + * @param id 编号 + * @return 支付应用信息 + */ + PayAppDO getApp(Long id); + + /** + * 获得支付应用信息列表 + * + * @param ids 编号 + * @return 支付应用信息列表 + */ + List getAppList(Collection ids); + + /** + * 获得支付应用信息分页 + * + * @param pageReqVO 分页查询 + * @return 支付应用信息分页 + */ + PageResult getAppPage(PayAppPageReqVO pageReqVO); + + /** + * 获得支付应用信息列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 支付应用信息列表 + */ + List getAppList(PayAppExportReqVO exportReqVO); + + /** + * 修改应用信息状态 + * + * @param id 应用编号 + * @param status 状态{@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} + */ + void updateAppStatus(Long id, Integer status); + + /** + * 根据商户 ID 获得支付应用信息列表, + * + * @param merchantId 商户 ID + * @return 支付应用信息列表 + */ + List getListByMerchantId(String merchantId); + + /** + * 获得指定编号的商户 Map + * + * @param appIdList 应用编号集合 + * @return 商户 Map + */ + default Map getAppMap(Collection appIdList) { + List list = this.getAppList(appIdList); + return CollectionUtils.convertMap(list, PayAppDO::getId); + } + + + /** + * 支付应用的合法性 + * + * 如果不合法,抛出 {@link ServiceException} 业务异常 + * + * @param id 应用编号 + * @return 应用信息 + */ + PayAppDO validPayApp(Long id); + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceImpl.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceImpl.java new file mode 100644 index 0000000..f7d1a4e --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceImpl.java @@ -0,0 +1,189 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppUpdateReqVO; +import cn.iocoder.yudao.module.pay.convert.app.PayAppConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayAppMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayMerchantMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +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 org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; + +/** + * 支付应用信息 Service 实现类 + * + * @author aquan + */ +@Service +@Validated +public class PayAppServiceImpl implements PayAppService { + + @Resource + private PayAppMapper appMapper; + // TODO @aquan:使用对方的 Service。模块与模块之间,避免直接调用对方的 mapper + @Resource + private PayMerchantMapper merchantMapper; + @Resource + private PayOrderMapper orderMapper; + @Resource + private PayRefundMapper refundMapper; + + @Override + public Long createApp(PayAppCreateReqVO createReqVO) { + // 插入 + PayAppDO app = PayAppConvert.INSTANCE.convert(createReqVO); + appMapper.insert(app); + // 返回 + return app.getId(); + } + + @Override + public void updateApp(PayAppUpdateReqVO updateReqVO) { + // 校验存在 + this.validateAppExists(updateReqVO.getId()); + // 更新 + PayAppDO updateObj = PayAppConvert.INSTANCE.convert(updateReqVO); + appMapper.updateById(updateObj); + } + + @Override + public void deleteApp(Long id) { + // 校验存在 + this.validateAppExists(id); + this.validateOrderTransactionExist(id); + + // 删除 + appMapper.deleteById(id); + } + + private void validateAppExists(Long id) { + if (appMapper.selectById(id) == null) { + throw exception(PAY_APP_NOT_FOUND); + } + } + + @Override + public PayAppDO getApp(Long id) { + return appMapper.selectById(id); + } + + @Override + public List getAppList(Collection ids) { + return appMapper.selectBatchIds(ids); + } + + @Override + public PageResult getAppPage(PayAppPageReqVO pageReqVO) { + Set merchantIdList = this.getMerchantCondition(pageReqVO.getMerchantName()); + if (StrUtil.isNotBlank(pageReqVO.getMerchantName()) && CollectionUtil.isEmpty(merchantIdList)) { + return new PageResult<>(); + } + return appMapper.selectPage(pageReqVO, merchantIdList); + } + + @Override + public List getAppList(PayAppExportReqVO exportReqVO) { + Set merchantIdList = this.getMerchantCondition(exportReqVO.getMerchantName()); + if (StrUtil.isNotBlank(exportReqVO.getMerchantName()) && CollectionUtil.isEmpty(merchantIdList)) { + return new ArrayList<>(); + } + return appMapper.selectList(exportReqVO, merchantIdList); + } + + /** + * 获取商户编号集合,根据商户名称模糊查询得到所有的商户编号集合 + * + * @param merchantName 商户名称 + * @return 商户编号集合 + */ + private Set getMerchantCondition(String merchantName) { + if (StrUtil.isBlank(merchantName)) { + return Collections.emptySet(); + } + return convertSet(merchantMapper.getMerchantListByName(merchantName), PayMerchantDO::getId); + } + + @Override + public void updateAppStatus(Long id, Integer status) { + // 校验商户存在 + this.checkAppExists(id); + // 更新状态 + PayAppDO app = new PayAppDO(); + app.setId(id); + app.setStatus(status); + appMapper.updateById(app); + } + + @Override + public List getListByMerchantId(String merchantId) { + return appMapper.getListByMerchantId(merchantId); + } + + /** + * 检查商户是否存在 + * + * @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); + // 校验是否存在 + if (app == null) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_APP_NOT_FOUND); + } + // 校验是否禁用 + if (CommonStatusEnum.DISABLE.getStatus().equals(app.getStatus())) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_APP_IS_DISABLE); + } + return app; + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelService.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelService.java new file mode 100644 index 0000000..3907b0e --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelService.java @@ -0,0 +1,133 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.iocoder.yudao.framework.common.exception.ServiceException; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelUpdateReqVO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; + +/** + * 支付渠道 Service 接口 + * + * @author aquan + */ +public interface PayChannelService { + + /** + * 初始化支付客户端 + */ + void initPayClients(); + + /** + * 创建支付渠道 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createChannel(@Valid PayChannelCreateReqVO createReqVO); + + /** + * 更新支付渠道 + * + * @param updateReqVO 更新信息 + */ + void updateChannel(@Valid PayChannelUpdateReqVO updateReqVO); + + /** + * 删除支付渠道 + * + * @param id 编号 + */ + void deleteChannel(Long id); + + /** + * 获得支付渠道 + * + * @param id 编号 + * @return 支付渠道 + */ + PayChannelDO getChannel(Long id); + + /** + * 获得支付渠道列表 + * + * @param ids 编号 + * @return 支付渠道 + * 列表 + */ + List getChannelList(Collection ids); + + /** + * 获得支付渠道分页 + * + * @param pageReqVO 分页查询 + * @return 支付渠道 + * 分页 + */ + PageResult getChannelPage(PayChannelPageReqVO pageReqVO); + + /** + * 获得支付渠道 + * 列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 支付渠道列表 + */ + List getChannelList(PayChannelExportReqVO exportReqVO); + + /** + * 根据支付应用ID集合获得支付渠道列表 + * + * @param appIds 应用编号集合 + * @return 支付渠道列表 + */ + List getChannelListByAppIds(Collection appIds); + + /** + * 根据条件获取渠道数量 + * + * @param merchantId 商户编号 + * @param appid 应用编号 + * @param code 渠道编码 + * @return 数量 + */ + Integer getChannelCountByConditions(Long merchantId, Long appid, String code); + + /** + * 根据条件获取渠道 + * + * @param merchantId 商户编号 + * @param appid 应用编号 + * @param code 渠道编码 + * @return 数量 + */ + PayChannelDO getChannelByConditions(Long merchantId, Long appid, String code); + + /** + * 支付渠道的合法性 + * + * 如果不合法,抛出 {@link ServiceException} 业务异常 + * + * @param id 渠道编号 + * @return 渠道信息 + */ + PayChannelDO validPayChannel(Long id); + + /** + * 支付渠道的合法性 + * + * 如果不合法,抛出 {@link ServiceException} 业务异常 + * + * @param appId 应用编号 + * @param code 支付渠道 + * @return 渠道信息 + */ + PayChannelDO validPayChannel(Long appId, String code); + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceImpl.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceImpl.java new file mode 100644 index 0000000..68b6ff1 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceImpl.java @@ -0,0 +1,250 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelUpdateReqVO; +import cn.iocoder.yudao.module.pay.convert.channel.PayChannelConvert; +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayChannelMapper; +import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import javax.validation.Validator; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; + +/** + * 支付渠道 Service 实现类 + * + * @author aquan + */ +@Service +@Slf4j +@Validated +public class PayChannelServiceImpl implements PayChannelService { + + /** + * 定时执行 {@link #schedulePeriodicRefresh()} 的周期 + * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高 + */ + private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L; + + /** + * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新 + */ + private volatile Date maxUpdateTime; + + @Resource + private PayClientFactory payClientFactory; + + @Resource + private PayChannelMapper channelMapper; + + @Resource + private Validator validator; + + @Override + @PostConstruct + public void initPayClients() { + // 获取支付渠道,如果有更新 + List payChannels = this.loadPayChannelIfUpdate(maxUpdateTime); + if (CollUtil.isEmpty(payChannels)) { + return; + } + + // 创建或更新支付 Client + payChannels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(), + payChannel.getCode(), payChannel.getConfig())); + + // 写入缓存 + assert payChannels.size() > 0; // 断言,避免告警 + maxUpdateTime = payChannels.stream().max(Comparator.comparing(BaseDO::getUpdateTime)).get().getUpdateTime(); + log.info("[initPayClients][初始化 PayChannel 数量为 {}]", payChannels.size()); + } + + @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD) + public void schedulePeriodicRefresh() { + initPayClients(); + } + + /** + * 如果支付渠道发生变化,从数据库中获取最新的全量支付渠道。 + * 如果未发生变化,则返回空 + * + * @param maxUpdateTime 当前支付渠道的最大更新时间 + * @return 支付渠道列表 + */ + private List loadPayChannelIfUpdate(Date maxUpdateTime) { + // 第一步,判断是否要更新。 + if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据 + log.info("[loadPayChannelIfUpdate][首次加载全量支付渠道]"); + } else { // 判断数据库中是否有更新的支付渠道 + if (channelMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) { + return null; + } + log.info("[loadPayChannelIfUpdate][增量加载全量支付渠道]"); + } + // 第二步,如果有更新,则从数据库加载所有支付渠道 + return channelMapper.selectList(); + } + + @Override + public Long createChannel(PayChannelCreateReqVO reqVO) { + // 断言是否有重复的 + PayChannelDO channelDO = this.getChannelByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode()); + if (ObjectUtil.isNotNull(channelDO)) { + throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR); + } + + // 新增渠道 + PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO); + settingConfigAndCheckParam(channel, reqVO.getConfig()); + channelMapper.insert(channel); + return channel.getId(); + } + + @Override + public void updateChannel(PayChannelUpdateReqVO updateReqVO) { + // 校验存在 + this.validateChannelExists(updateReqVO.getId()); + // 更新 + PayChannelDO channel = PayChannelConvert.INSTANCE.convert(updateReqVO); + settingConfigAndCheckParam(channel, updateReqVO.getConfig()); + channelMapper.updateById(channel); + } + + @Override + public void deleteChannel(Long id) { + // 校验存在 + this.validateChannelExists(id); + // 删除 + channelMapper.deleteById(id); + } + + private void validateChannelExists(Long id) { + if (channelMapper.selectById(id) == null) { + throw exception(CHANNEL_NOT_EXISTS); + } + } + + @Override + public PayChannelDO getChannel(Long id) { + return channelMapper.selectById(id); + } + + @Override + public List getChannelList(Collection ids) { + return channelMapper.selectBatchIds(ids); + } + + @Override + public PageResult getChannelPage(PayChannelPageReqVO pageReqVO) { + return channelMapper.selectPage(pageReqVO); + } + + @Override + public List getChannelList(PayChannelExportReqVO exportReqVO) { + return channelMapper.selectList(exportReqVO); + } + + /** + * 根据支付应用ID集合获得支付渠道列表 + * + * @param appIds 应用编号集合 + * @return 支付渠道列表 + */ + @Override + public List getChannelListByAppIds(Collection appIds) { + return channelMapper.getChannelListByAppIds(appIds); + } + + + /** + * 根据条件获取渠道数量 + * + * @param merchantId 商户编号 + * @param appid 应用编号 + * @param code 渠道编码 + * @return 数量 + */ + @Override + public Integer getChannelCountByConditions(Long merchantId, Long appid, String code) { + return this.channelMapper.selectCount(merchantId, appid, code); + } + + /** + * 根据条件获取渠道 + * + * @param merchantId 商户编号 + * @param appid 应用编号 + * @param code 渠道编码 + * @return 数量 + */ + @Override + public PayChannelDO getChannelByConditions(Long merchantId, Long appid, String code) { + return this.channelMapper.selectOne(merchantId, appid, code); + } + + /** + * 设置渠道配置以及参数校验 + * + * @param channel 渠道 + * @param configStr 配置 + */ + private void settingConfigAndCheckParam(PayChannelDO channel, String configStr) { + // 得到这个渠道是微信的还是支付宝的 + Class payClass = PayChannelEnum.getByCode(channel.getCode()).getConfigClass(); + if (ObjectUtil.isNull(payClass)) { + throw exception(CHANNEL_NOT_EXISTS); + } + PayClientConfig config = JSONUtil.toBean(configStr, payClass); + + // 验证参数 + config.validate(validator); + channel.setConfig(config); + } + + @Override + public PayChannelDO validPayChannel(Long id) { + PayChannelDO channel = channelMapper.selectById(id); + this.validPayChannel(channel); + return channel; + } + + @Override + public PayChannelDO validPayChannel(Long appId, String code) { + PayChannelDO channel = channelMapper.selectByAppIdAndCode(appId, code); + this.validPayChannel(channel); + return channel; + } + + private void validPayChannel(PayChannelDO channel) { + if (channel == null) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_NOT_FOUND); + } + if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_IS_DISABLE); + } + } +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantService.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantService.java new file mode 100644 index 0000000..40f02b9 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantService.java @@ -0,0 +1,104 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantUpdateReqVO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 支付商户信息 Service 接口 + * + * @author aquan + */ +public interface PayMerchantService { + + /** + * 创建支付商户信息 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createMerchant(@Valid PayMerchantCreateReqVO createReqVO); + + /** + * 更新支付商户信息 + * + * @param updateReqVO 更新信息 + */ + void updateMerchant(@Valid PayMerchantUpdateReqVO updateReqVO); + + /** + * 删除支付商户信息 + * + * @param id 编号 + */ + void deleteMerchant(Long id); + + /** + * 获得支付商户信息 + * + * @param id 编号 + * @return 支付商户信息 + */ + PayMerchantDO getMerchant(Long id); + + /** + * 获得支付商户信息列表 + * + * @param ids 编号 + * @return 支付商户信息列表 + */ + List getMerchantList(Collection ids); + + /** + * 获得支付商户信息分页 + * + * @param pageReqVO 分页查询 + * @return 支付商户信息分页 + */ + PageResult getMerchantPage(PayMerchantPageReqVO pageReqVO); + + /** + * 获得支付商户信息列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 支付商户信息列表 + */ + List getMerchantList(PayMerchantExportReqVO exportReqVO); + + /** + * 修改商户状态 + * + * @param id 商户编号 + * @param status 状态 + */ + void updateMerchantStatus(Long id, Integer status); + + /** + * 根据商户名称模糊查询商户集合 + * + * @param merchantName 商户名称 + * @return 商户集合 + */ + List getMerchantListByName(String merchantName); + + /** + * 获得指定编号的商户 Map + * + * @param merchantIds 商户编号数组 + * @return 商户 Map + */ + default Map getMerchantMap(Collection merchantIds) { + List list = this.getMerchantList(merchantIds); + return CollectionUtils.convertMap(list, PayMerchantDO::getId); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceImpl.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceImpl.java new file mode 100644 index 0000000..c14a87d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceImpl.java @@ -0,0 +1,148 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantUpdateReqVO; +import cn.iocoder.yudao.module.pay.convert.merchant.PayMerchantConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayAppMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayMerchantMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import com.google.common.annotations.VisibleForTesting; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +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.*; + +/** + * 支付商户信息 Service 实现类 + * + * @author aquan + */ +@Service +@Validated +public class PayMerchantServiceImpl implements PayMerchantService { + + @Resource + private PayMerchantMapper merchantMapper; + + @Resource + private PayAppMapper appMapper; + + @Override + public Long createMerchant(PayMerchantCreateReqVO createReqVO) { + // 插入 + PayMerchantDO merchant = PayMerchantConvert.INSTANCE.convert(createReqVO); + merchant.setNo(this.generateMerchantNo()); + merchantMapper.insert(merchant); + // 返回 + return merchant.getId(); + } + + @Override + public void updateMerchant(PayMerchantUpdateReqVO updateReqVO) { + // 校验存在 + this.validateMerchantExists(updateReqVO.getId()); + // 更新 + PayMerchantDO updateObj = PayMerchantConvert.INSTANCE.convert(updateReqVO); + merchantMapper.updateById(updateObj); + } + + @Override + public void deleteMerchant(Long id) { + // 校验 + this.validateMerchantExists(id); + this.validateAppExists(id); + // 删除 + merchantMapper.deleteById(id); + } + + @Override + public PayMerchantDO getMerchant(Long id) { + return merchantMapper.selectById(id); + } + + @Override + public List getMerchantList(Collection ids) { + return merchantMapper.selectBatchIds(ids); + } + + @Override + public PageResult getMerchantPage(PayMerchantPageReqVO pageReqVO) { + return merchantMapper.selectPage(pageReqVO); + } + + @Override + public List getMerchantList(PayMerchantExportReqVO exportReqVO) { + return merchantMapper.selectList(exportReqVO); + } + + @Override + public void updateMerchantStatus(Long id, Integer status) { + // 校验商户存在 + this.checkMerchantExists(id); + // 更新状态 + PayMerchantDO merchant = new PayMerchantDO(); + merchant.setId(id); + merchant.setStatus(status); + merchantMapper.updateById(merchant); + } + + @Override + public List getMerchantListByName(String merchantName) { + return this.merchantMapper.getMerchantListByName(merchantName); + } + + @VisibleForTesting + public void checkMerchantExists(Long id) { + if (id == null) { + return; + } + PayMerchantDO merchant = merchantMapper.selectById(id); + if (merchant == null) { + throw exception(PAY_MERCHANT_NOT_EXISTS); + } + } + + /** + * 校验商户是否存在 + * + * @param id 商户 ID + */ + private void validateMerchantExists(Long id) { + if (ObjectUtil.isNull(merchantMapper.selectById(id))) { + throw exception(PAY_MERCHANT_NOT_EXISTS); + } + } + + /** + * 校验商户是否还存在支付应用 + * + * @param id 商户ID + */ + private void validateAppExists(Long id) { + if (appMapper.selectCount(id) > 0) { + throw exception(PAY_MERCHANT_EXIST_APP_CANT_DELETE); + } + } + + // TODO @芋艿:后续增加下合适的算法 + /** + * 根据年月日时分秒毫秒生成商户号 + * + * @return 商户号 + */ + private String generateMerchantNo() { + return "M" + DateUtil.format(LocalDateTime.now(), "yyyyMMddHHmmssSSS"); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyService.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyService.java new file mode 100644 index 0000000..92358e4 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyService.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.pay.service.notify; + +import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; + +import javax.validation.Valid; + +/** + * 支付通知 Service 接口 + * + * @author 芋道源码 + */ +public interface PayNotifyService { + + /** + * 创建支付通知任务 + * + * @param reqDTO 任务信息 + */ + void createPayNotifyTask(@Valid PayNotifyTaskCreateReqDTO reqDTO); + + /** + * 执行支付通知 + * + * 注意,该方法提供给定时任务调用。目前是 yudao-admin-server 进行调用 + * @return 通知数量 + */ + int executeNotify() throws InterruptedException; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java new file mode 100644 index 0000000..1d5091a --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/PayNotifyServiceImpl.java @@ -0,0 +1,258 @@ +package cn.iocoder.yudao.module.pay.service.notify; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.exceptions.ExceptionUtil; +import cn.hutool.http.HttpUtil; +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyLogDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.notify.PayNotifyTaskDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyLogCoreMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskCoreMapper; +import cn.iocoder.yudao.module.pay.dal.redis.notify.PayNotifyLockRedisDAO; +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyStatusEnum; +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; +import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; +import cn.iocoder.yudao.module.pay.service.notify.vo.PayNotifyOrderReqVO; +import cn.iocoder.yudao.module.pay.service.notify.vo.PayRefundOrderReqVO; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Lazy; +import org.springframework.scheduling.annotation.Async; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * 支付通知 Core Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Valid +@Slf4j +public class PayNotifyServiceImpl implements PayNotifyService { + + /** + * 通知超时时间,单位:秒 + */ + public static final int NOTIFY_TIMEOUT = 120; + /** + * {@link #NOTIFY_TIMEOUT} 的毫秒 + */ + public static final long NOTIFY_TIMEOUT_MILLIS = 120 * DateUtils.SECOND_MILLIS; + + @Resource + @Lazy // 循环依赖,避免报错 + private PayOrderService orderService; + @Resource + @Lazy // 循环依赖,避免报错 + private PayRefundService refundService; + + @Resource + private PayNotifyTaskCoreMapper payNotifyTaskCoreMapper; + @Resource + private PayNotifyLogCoreMapper payNotifyLogCoreMapper; + + @Resource + private ThreadPoolTaskExecutor threadPoolTaskExecutor; // TODO 芋艿:未来提供独立的线程池 + + @Resource + private PayNotifyLockRedisDAO payNotifyLockCoreRedisDAO; + + @Resource + @Lazy // 循环依赖(自己依赖自己),避免报错 + private PayNotifyServiceImpl self; + + @Override + public void createPayNotifyTask(PayNotifyTaskCreateReqDTO reqDTO) { + PayNotifyTaskDO task = new PayNotifyTaskDO(); + task.setType(reqDTO.getType()).setDataId(reqDTO.getDataId()); + task.setStatus(PayNotifyStatusEnum.WAITING.getStatus()).setNextNotifyTime(new Date()) + .setNotifyTimes(0).setMaxNotifyTimes(PayNotifyTaskDO.NOTIFY_FREQUENCY.length + 1); + // 补充 merchantId + appId + notifyUrl 字段 + if (Objects.equals(task.getType(), PayNotifyTypeEnum.ORDER.getType())) { + PayOrderDO order = orderService.getOrder(task.getDataId()); // 不进行非空判断,有问题直接异常 + task.setMerchantId(order.getMerchantId()).setAppId(order.getAppId()). + setMerchantOrderId(order.getMerchantOrderId()).setNotifyUrl(order.getNotifyUrl()); + } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) { + PayRefundDO refundDO = refundService.getRefund(task.getDataId()); + task.setMerchantId(refundDO.getMerchantId()).setAppId(refundDO.getAppId()) + .setMerchantOrderId(refundDO.getMerchantOrderId()).setNotifyUrl(refundDO.getNotifyUrl()); + } + + // 执行插入 + payNotifyTaskCoreMapper.insert(task); + + // 异步直接发起任务。虽然会有定时任务扫描,但是会导致延迟 + self.executeNotifyAsync(task); + } + + @Override + public int executeNotify() throws InterruptedException { + // 获得需要通知的任务 + List tasks = payNotifyTaskCoreMapper.selectListByNotify(); + if (CollUtil.isEmpty(tasks)) { + return 0; + } + + // 遍历,逐个通知 + CountDownLatch latch = new CountDownLatch(tasks.size()); + tasks.forEach(task -> threadPoolTaskExecutor.execute(() -> { + try { + executeNotifySync(task); + } finally { + latch.countDown(); + } + })); + // 等待完成 + this.awaitExecuteNotify(latch); + // 返回执行完成的任务数(成功 + 失败) + return tasks.size(); + } + + /** + * 等待全部支付通知的完成 + * 每 1 秒会打印一次剩余任务数量 + * + * @param latch Latch + * @throws InterruptedException 如果被打断 + */ + private void awaitExecuteNotify(CountDownLatch latch) throws InterruptedException { + long size = latch.getCount(); + for (int i = 0; i < NOTIFY_TIMEOUT; i++) { + if (latch.await(1L, TimeUnit.SECONDS)) { + return; + } + log.info("[awaitExecuteNotify][任务处理中, 总任务数({}) 剩余任务数({})]", size, latch.getCount()); + } + log.error("[awaitExecuteNotify][任务未处理完,总任务数({}) 剩余任务数({})]", size, latch.getCount()); + } + + /** + * 异步执行单个支付通知 + * + * @param task 通知任务 + */ + @Async + public void executeNotifyAsync(PayNotifyTaskDO task) { + self.executeNotifySync(task); // 使用 self,避免事务不发起 + } + + /** + * 同步执行单个支付通知 + * + * @param task 通知任务 + */ + public void executeNotifySync(PayNotifyTaskDO task) { + // 分布式锁,避免并发问题 + payNotifyLockCoreRedisDAO.lock(task.getId(), NOTIFY_TIMEOUT_MILLIS, () -> { + // 校验,当前任务是否已经被通知过 + // 虽然已经通过分布式加锁,但是可能同时满足通知的条件,然后都去获得锁。此时,第一个执行完后,第二个还是能拿到锁,然后会再执行一次。 + PayNotifyTaskDO dbTask = payNotifyTaskCoreMapper.selectById(task.getId()); + if (DateUtils.afterNow(dbTask.getNextNotifyTime())) { + log.info("[executeNotify][dbTask({}) 任务被忽略,原因是未到达下次通知时间,可能是因为并发执行了]", JsonUtils.toJsonString(dbTask)); + return; + } + + // 执行通知 + executeNotify(dbTask); + }); + } + + @Transactional + public void executeNotify(PayNotifyTaskDO task) { + // 发起回调 + CommonResult invokeResult = null; + Throwable invokeException = null; + try { + invokeResult = executeNotifyInvoke(task); + } catch (Throwable e) { + invokeException = e; + } + + // 处理 + Integer newStatus = this.processNotifyResult(task, invokeResult, invokeException); + + // 记录 PayNotifyLog 日志 + String response = invokeException != null ? ExceptionUtil.getRootCauseMessage(invokeException) : JsonUtils.toJsonString(invokeResult); + payNotifyLogCoreMapper.insert(PayNotifyLogDO.builder().taskId(task.getId()) + .notifyTimes(task.getNotifyTimes() + 1).status(newStatus).response(response).build()); + } + + /** + * 执行单个支付任务的 HTTP 调用 + * + * @param task 通知任务 + * @return HTTP 响应 + */ + private CommonResult executeNotifyInvoke(PayNotifyTaskDO task) { + // 拼接参数 + Object request; + if (Objects.equals(task.getType(), PayNotifyTypeEnum.ORDER.getType())) { + request = PayNotifyOrderReqVO.builder().merchantOrderId(task.getMerchantOrderId()) + .payOrderId(task.getDataId()).build(); + } else if (Objects.equals(task.getType(), PayNotifyTypeEnum.REFUND.getType())) { + request = PayRefundOrderReqVO.builder().merchantOrderId(task.getMerchantOrderId()) + .payRefundId(task.getDataId()).build(); + } else { + throw new RuntimeException("未知的通知任务类型:" + JsonUtils.toJsonString(task)); + } + // 请求地址 + String response = HttpUtil.post(task.getNotifyUrl(), JsonUtils.toJsonString(request), + (int) NOTIFY_TIMEOUT_MILLIS); + // 解析结果 + return JsonUtils.parseObject(response, CommonResult.class); + } + + /** + * 处理并更新通知结果 + * + * @param task 通知任务 + * @param invokeResult 通知结果 + * @param invokeException 通知异常 + * @return 最终任务的状态 + */ + private Integer processNotifyResult(PayNotifyTaskDO task, CommonResult invokeResult, Throwable invokeException) { + // 设置通用的更新 PayNotifyTaskDO 的字段 + PayNotifyTaskDO updateTask = new PayNotifyTaskDO() + .setId(task.getId()) + .setLastExecuteTime(new Date()) + .setNotifyTimes(task.getNotifyTimes() + 1); + + // 情况一:调用成功 + if (invokeResult != null && invokeResult.isSuccess()) { + updateTask.setStatus(PayNotifyStatusEnum.SUCCESS.getStatus()); + return updateTask.getStatus(); + } + // 情况二:调用失败、调用异常 + // 2.1 超过最大回调次数 + if (updateTask.getNotifyTimes() >= PayNotifyTaskDO.NOTIFY_FREQUENCY.length) { + updateTask.setStatus(PayNotifyStatusEnum.FAILURE.getStatus()); + return updateTask.getStatus(); + } + // 2.2 未超过最大回调次数 + updateTask.setNextNotifyTime(DateUtils.addDate(Calendar.SECOND, PayNotifyTaskDO.NOTIFY_FREQUENCY[updateTask.getNotifyTimes()])); + updateTask.setStatus(invokeException != null ? PayNotifyStatusEnum.REQUEST_FAILURE.getStatus() + : PayNotifyStatusEnum.REQUEST_SUCCESS.getStatus()); + return updateTask.getStatus(); + } + + private void processNotifySuccess(PayNotifyTaskDO task, PayNotifyTaskDO updateTask) { + payNotifyTaskCoreMapper.updateById(updateTask); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java new file mode 100644 index 0000000..49d570d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/dto/PayNotifyTaskCreateReqDTO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.pay.service.notify.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; + +/** + * 支付通知创建 DTO + * + * @author 芋道源码 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayNotifyTaskCreateReqDTO { + + /** + * 类型 + */ + @NotNull(message = "类型不能为空") + private Integer type; + /** + * 数据编号 + */ + @NotNull(message = "数据编号不能为空") + private Long dataId; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java new file mode 100644 index 0000000..d4f6c1e --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayNotifyOrderReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.pay.service.notify.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@ApiModel(value = "支付单的通知 Request VO", description = "业务方接入支付回调时,使用该 VO 对象") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayNotifyOrderReqVO { + + @ApiModelProperty(value = "商户订单编号", required = true, example = "10") + @NotEmpty(message = "商户订单号不能为空") + private String merchantOrderId; + + @ApiModelProperty(value = "支付订单编号", required = true, example = "20") + @NotNull(message = "支付订单编号不能为空") + private Long payOrderId; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java new file mode 100644 index 0000000..978283d --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/PayRefundOrderReqVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.pay.service.notify.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@ApiModel(value = "退款单的通知 Request VO", description = "业务方接入退款回调时,使用该 VO 对象") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayRefundOrderReqVO { + + @ApiModelProperty(value = "商户退款单编号", required = true, example = "10") + @NotEmpty(message = "商户退款单编号不能为空") + private String merchantOrderId; + + @ApiModelProperty(value = "支付退款编号", required = true, example = "20") + @NotNull(message = "支付退款编号不能为空") + private Long payRefundId; + + @ApiModelProperty(value = "退款状态(成功,失败)", required = true, example = "10") + private Integer status; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/package-info.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/package-info.java new file mode 100644 index 0000000..fb006dd --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/notify/vo/package-info.java @@ -0,0 +1,6 @@ +/** + * 这里的 VO 包有点特殊,是提供给接入支付模块的业务,提供回调接口时,可以直接使用 VO + * + * 例如说,支付单的回调,使用 TODO 芋艿:想下怎么优化下 + */ +package cn.iocoder.yudao.module.pay.service.notify.vo; diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionService.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionService.java new file mode 100755 index 0000000..f707bc0 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionService.java @@ -0,0 +1,46 @@ +package cn.iocoder.yudao.module.pay.service.order; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 支付订单 Service 接口 + * + * @author aquan + */ +public interface PayOrderExtensionService { + + /** + * 获得支付订单 + * + * @param id 编号 + * @return 支付订单 + */ + PayOrderExtensionDO getOrderExtension(Long id); + + /** + * 获得支付订单 + * 列表 + * + * @param ids 编号 + * @return 支付订单 + * 列表 + */ + List getOrderExtensionList(Collection ids); + + /** + * 根据订单成功的 扩展订单ID 查询所有的扩展订单转 成 map 返回 + * + * @param successExtensionIdList 订单 ID 集合 + * @return 订单扩展 map 集合 + */ + default Map getOrderExtensionMap(Collection successExtensionIdList) { + List list = getOrderExtensionList(successExtensionIdList); + return CollectionUtils.convertMap(list, PayOrderExtensionDO::getId); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionServiceImpl.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionServiceImpl.java new file mode 100755 index 0000000..a97e3be --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderExtensionServiceImpl.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.pay.service.order; + +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.List; + +/** + * 支付订单 Service 实现类 + * + * @author aquan + */ +@Service +@Validated +public class PayOrderExtensionServiceImpl implements PayOrderExtensionService { + + @Resource + private PayOrderExtensionMapper orderExtensionMapper; + + @Override + public PayOrderExtensionDO getOrderExtension(Long id) { + return orderExtensionMapper.selectById(id); + } + + @Override + public List getOrderExtensionList(Collection ids) { + return orderExtensionMapper.selectBatchIds(ids); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java new file mode 100755 index 0000000..40ed287 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java @@ -0,0 +1,97 @@ +package cn.iocoder.yudao.module.pay.service.order; + +import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitRespDTO; + +import javax.validation.Valid; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * 支付订单 Service 接口 + * + * @author aquan + */ +public interface PayOrderService { + + /** + * 获得支付订单 + * + * @param id 编号 + * @return 支付订单 + */ + PayOrderDO getOrder(Long id); + + /** + * 获得支付订单 + * 分页 + * + * @param pageReqVO 分页查询 + * @return 支付订单 + * 分页 + */ + PageResult getOrderPage(PayOrderPageReqVO pageReqVO); + + /** + * 获得支付订单 + * 列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 支付订单 + * 列表 + */ + List getOrderList(PayOrderExportReqVO exportReqVO); + + /** + * 根据 ID 集合获取只包含商品名称的订单集合 + * + * @param idList 订单 ID 集合 + * @return 只包含商品名称的订单集合 + */ + List getOrderSubjectList(Collection idList); + + /** + * 根据订单 ID 集合获取订单商品名称Map集合 + * + * @param idList 订单 ID 集合 + * @return 订单商品 map 集合 + */ + default Map getOrderSubjectMap(Collection idList) { + List list = getOrderSubjectList(idList); + return CollectionUtils.convertMap(list, PayOrderDO::getId); + } + + /** + * 创建支付单 + * + * @param reqDTO 创建请求 + * @return 支付单编号 + */ + Long createPayOrder(@Valid PayOrderCreateReqDTO reqDTO); + + /** + * 提交支付 + * 此时,会发起支付渠道的调用 + * + * @param reqDTO 提交请求 + * @return 提交结果 + */ + PayOrderSubmitRespDTO submitPayOrder(@Valid PayOrderSubmitReqDTO reqDTO); + + /** + * 通知支付单成功 + * + * @param channelId 渠道编号 + * @param notifyData 通知数据 + */ + void notifyPayOrder(Long channelId, PayNotifyDataDTO notifyData) throws Exception; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java new file mode 100755 index 0000000..72bfac0 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java @@ -0,0 +1,273 @@ +package cn.iocoder.yudao.module.pay.service.order; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.pay.config.PayProperties; +import cn.iocoder.yudao.framework.pay.core.client.PayClient; +import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderNotifyRespDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO; +import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderExtensionMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper; +import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.pay.service.merchant.PayAppService; +import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService; +import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; +import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderCreateReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayOrderSubmitRespDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + * 支付订单 Service 实现类 + * + * @author aquan + */ +@Service +@Validated +@Slf4j +public class PayOrderServiceImpl implements PayOrderService { + + @Resource + private PayProperties payProperties; + + @Resource + private PayClientFactory payClientFactory; + + @Resource + private PayOrderMapper orderMapper; + @Resource + private PayOrderExtensionMapper orderExtensionMapper; + + @Resource + private PayAppService appService; + @Resource + private PayChannelService channelService; + @Resource + private PayNotifyService notifyService; + + @Override + public PayOrderDO getOrder(Long id) { + return orderMapper.selectById(id); + } + + @Override + public PageResult getOrderPage(PayOrderPageReqVO pageReqVO) { + return orderMapper.selectPage(pageReqVO); + } + + @Override + public List getOrderList(PayOrderExportReqVO exportReqVO) { + return orderMapper.selectList(exportReqVO); + } + + // TODO @艿艿:需要优化。不确定这个方法的作用 + @Override + public List getOrderSubjectList(Collection idList) { + return orderMapper.findByIdListQueryOrderSubject(idList); + } + + @Override + public Long createPayOrder(PayOrderCreateReqDTO reqDTO) { + // 校验 App + PayAppDO app = appService.validPayApp(reqDTO.getAppId()); + + // 查询对应的支付交易单是否已经存在。如果是,则直接返回 + PayOrderDO order = orderMapper.selectByAppIdAndMerchantOrderId( + reqDTO.getAppId(), reqDTO.getMerchantOrderId()); + if (order != null) { + log.warn("[createPayOrder][appId({}) merchantOrderId({}) 已经存在对应的支付单({})]", order.getAppId(), + order.getMerchantOrderId(), JsonUtils.toJsonString(order)); // 理论来说,不会出现这个情况 + return app.getId(); + } + + // 创建支付交易单 + order = PayOrderConvert.INSTANCE.convert(reqDTO) + .setMerchantId(app.getMerchantId()).setAppId(app.getId()); + // 商户相关字段 + order.setNotifyUrl(app.getPayNotifyUrl()) + .setNotifyStatus(PayOrderNotifyStatusEnum.NO.getStatus()); + // 订单相关字段 + order.setStatus(PayOrderStatusEnum.WAITING.getStatus()); + // 退款相关字段 + // todo @芋艿 创建支付的订单的退款状态枚举是不是有问题,应该是 PayRefundTypeEnum 吧 您这填写的是 PayOrderNotifyStatusEnum 回调状态枚举 + order.setRefundStatus(PayOrderNotifyStatusEnum.NO.getStatus()) + .setRefundTimes(0).setRefundAmount(0L); + orderMapper.insert(order); + // 最终返回 + return order.getId(); + } + + @Override + public PayOrderSubmitRespDTO submitPayOrder(PayOrderSubmitReqDTO reqDTO) { + // 校验 App + appService.validPayApp(reqDTO.getAppId()); + // 校验支付渠道是否有效 + PayChannelDO channel = channelService.validPayChannel(reqDTO.getAppId(), reqDTO.getChannelCode()); + // 校验支付客户端是否正确初始化 + PayClient client = payClientFactory.getPayClient(channel.getId()); + if (client == null) { + log.error("[submitPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND); + } + + // 获得 PayOrderDO ,并校验其是否存在 + PayOrderDO order = orderMapper.selectById(reqDTO.getId()); + if (order == null || !Objects.equals(order.getAppId(), reqDTO.getAppId())) { // 是否存在 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_NOT_FOUND); + } + if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_WAITING); + } + + // 插入 PayOrderExtensionDO + PayOrderExtensionDO orderExtension = PayOrderConvert.INSTANCE.convert(reqDTO) + .setOrderId(order.getId()).setNo(generateOrderExtensionNo()) + .setChannelId(channel.getId()).setChannelCode(channel.getCode()) + .setStatus(PayOrderStatusEnum.WAITING.getStatus()); + orderExtensionMapper.insert(orderExtension); + + // 调用三方接口 + PayOrderUnifiedReqDTO unifiedOrderReqDTO = PayOrderConvert.INSTANCE.convert2(reqDTO); + // 商户相关字段 + //TODO jason @芋艿 是否加一个属性 如tradeNo 支付订单号, 用这个merchantOrderId让人迷糊 + unifiedOrderReqDTO.setMerchantOrderId(orderExtension.getNo()) // 注意,此处使用的是 PayOrderExtensionDO.no 属性! + .setSubject(order.getSubject()).setBody(order.getBody()) + .setNotifyUrl(genChannelPayNotifyUrl(channel)) + .setReturnUrl(genChannelReturnUrl(channel)); + // 订单相关字段 + unifiedOrderReqDTO.setAmount(order.getAmount()).setExpireTime(order.getExpireTime()); + CommonResult unifiedOrderResult = client.unifiedOrder(unifiedOrderReqDTO); + unifiedOrderResult.checkError(); + + // TODO 轮询三方接口,是否已经支付的任务 + // 返回成功 + return new PayOrderSubmitRespDTO().setExtensionId(orderExtension.getId()) + .setInvokeResponse(unifiedOrderResult.getData()); + } + + /** + * 根据支付渠道的编码,生成支付渠道的返回地址 + * @param channel 支付渠道 + * @return 支付成功返回的地址。 配置地址 + "/" + channel id + */ + private String genChannelReturnUrl(PayChannelDO channel) { + return payProperties.getPayReturnUrl() + "/" + channel.getId(); + } + + /** + * 根据支付渠道的编码,生成支付渠道的回调地址 + * + * @param channel 支付渠道 + * @return 支付渠道的回调地址 配置地址 + "/" + channel id + */ + private String genChannelPayNotifyUrl(PayChannelDO channel) { + //去掉channel code, 似乎没啥用, 用统一的回调地址 + return payProperties.getPayNotifyUrl() + "/" + channel.getId(); + } + + private String generateOrderExtensionNo() { +// wx +// 2014 +// 10 +// 27 +// 20 +// 09 +// 39 +// 5522657 +// a690389285100 + // 目前的算法 + // 时间序列,年月日时分秒 14 位 + // 纯随机,6 位 TODO 芋艿:此处估计是会有问题的,后续在调整 + return DateUtil.format(new Date(), "yyyyMMddHHmmss") + // 时间序列 + RandomUtil.randomInt(100000, 999999) // 随机。为什么是这个范围,因为偷懒 + ; + } + + @Override + @Transactional + public void notifyPayOrder(Long channelId, PayNotifyDataDTO notifyData) throws Exception { + // TODO 芋艿,记录回调日志 + log.info("[notifyPayOrder][channelId({}) 回调数据({})]", channelId, notifyData.getBody()); + + // 校验支付渠道是否有效 + PayChannelDO channel = channelService.validPayChannel(channelId); + // 校验支付客户端是否正确初始化 + PayClient client = payClientFactory.getPayClient(channel.getId()); + if (client == null) { + log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND); + } + + // 解析支付结果 + PayOrderNotifyRespDTO notifyRespDTO = client.parseOrderNotify(notifyData); + + // TODO 芋艿,先最严格的校验。即使调用方重复调用,实际哪个订单已经被重复回调的支付,也返回 false 。也没问题,因为实际已经回调成功了。 + // 1.1 查询 PayOrderExtensionDO + PayOrderExtensionDO orderExtension = orderExtensionMapper.selectByNo(notifyRespDTO.getOrderExtensionNo()); + if (orderExtension == null) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_EXTENSION_NOT_FOUND); + } + if (!PayOrderStatusEnum.WAITING.getStatus().equals(orderExtension.getStatus())) { // 校验状态,必须是待支付 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING); + } + // 1.2 更新 PayOrderExtensionDO + //TODO 支付宝交易超时 TRADE_FINISHED 需要更新交易关闭 + int updateCounts = orderExtensionMapper.updateByIdAndStatus(orderExtension.getId(), + PayOrderStatusEnum.WAITING.getStatus(), PayOrderExtensionDO.builder().id(orderExtension.getId()) + .status(PayOrderStatusEnum.SUCCESS.getStatus()).channelNotifyData(notifyData.getBody()).build()); + if (updateCounts == 0) { // 校验状态,必须是待支付 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING); + } + log.info("[notifyPayOrder][支付拓展单({}) 更新为已支付]", orderExtension.getId()); + + // 2.1 判断 PayOrderDO 是否处于待支付 + PayOrderDO order = orderMapper.selectById(orderExtension.getOrderId()); + if (order == null) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_NOT_FOUND); + } + if (!PayOrderStatusEnum.WAITING.getStatus().equals(order.getStatus())) { // 校验状态,必须是待支付 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_WAITING); + } + // 2.2 更新 PayOrderDO + updateCounts = orderMapper.updateByIdAndStatus(order.getId(), PayOrderStatusEnum.WAITING.getStatus(), + PayOrderDO.builder().status(PayOrderStatusEnum.SUCCESS.getStatus()).channelId(channelId).channelCode(channel.getCode()) + .successTime(notifyRespDTO.getSuccessTime()).successExtensionId(orderExtension.getId()) + .channelOrderNo(notifyRespDTO.getChannelOrderNo()).channelUserId(notifyRespDTO.getChannelUserId()) + .notifyTime(new Date()).build()); + if (updateCounts == 0) { // 校验状态,必须是待支付 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_WAITING); + } + log.info("[notifyPayOrder][支付订单({}) 更新为已支付]", order.getId()); + + // 3. 插入支付通知记录 + notifyService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() + .type(PayNotifyTypeEnum.ORDER.getType()).dataId(order.getId()).build()); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderCreateReqDTO.java new file mode 100644 index 0000000..62bf511 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderCreateReqDTO.java @@ -0,0 +1,64 @@ +package cn.iocoder.yudao.module.pay.service.order.dto; + +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; + +/** + * 支付单创建 Request DTO + */ +@Data +public class PayOrderCreateReqDTO implements Serializable { + + /** + * 应用编号 + */ + @NotNull(message = "应用编号不能为空") + private Long appId; + /** + * 用户 IP + */ + @NotEmpty(message = "用户 IP 不能为空") + private String userIp; + + // ========== 商户相关字段 ========== + + /** + * 商户订单编号 + */ + @NotEmpty(message = "商户订单编号不能为空") + private String merchantOrderId; + /** + * 商品标题 + */ + @NotEmpty(message = "商品标题不能为空") + @Length(max = 32, message = "商品标题不能超过 32") + private String subject; + /** + * 商品描述 + */ + @NotEmpty(message = "商品描述信息不能为空") + @Length(max = 128, message = "商品描述信息长度不能超过128") + private String body; + + // ========== 订单相关字段 ========== + + /** + * 支付金额,单位:分 + */ + @NotNull(message = "支付金额不能为空") + @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") + private Integer amount; + + /** + * 支付过期时间 + */ + @NotNull(message = "支付过期时间不能为空") + private Date expireTime; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitReqDTO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitReqDTO.java new file mode 100644 index 0000000..20f6ab2 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitReqDTO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.pay.service.order.dto; + +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Map; + +/** + * 支付单提交 Request DTO + */ +@Data +@Accessors(chain = true) +public class PayOrderSubmitReqDTO implements Serializable { + + /** + * 应用编号 + */ + @NotNull(message = "应用编号不能为空") + private Long appId; + + /** + * 支付单编号 + */ + @NotNull(message = "支付单编号不能为空") + private Long id; + + /** + * 支付渠道 + */ + @NotEmpty(message = "支付渠道不能为空") + private String channelCode; + + /** + * 用户 IP + */ + @NotEmpty(message = "用户 IP 不能为空") + private String userIp; + + /** + * 支付渠道的额外参数 + */ + private Map channelExtras; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitRespDTO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitRespDTO.java new file mode 100644 index 0000000..a594253 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayOrderSubmitRespDTO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.pay.service.order.dto; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 支付单提交 Response DTO + */ +@Data +public class PayOrderSubmitRespDTO implements Serializable { + + /** + * 支付拓展单的编号 + */ + private Long extensionId; + + /** + * 调用支付渠道的响应结果 + */ + private Object invokeResponse; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java new file mode 100644 index 0000000..0eb24db --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.pay.service.order.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import javax.validation.constraints.DecimalMin; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 退款申请单 Request DTO + */ +@Data +@Accessors(chain = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayRefundReqDTO { + + /** + * 支付订单编号 + */ + @NotNull(message = "支付订单编号不能为空") + private Long payOrderId; + + /** + * 退款金额 + */ + @NotNull(message = "退款金额不能为空") + @DecimalMin(value = "0", inclusive = false, message = "退款金额必须大于零") + private Long amount; + + /** + * 退款原因 + */ + private String reason; + + /** + * 商户退款订单号 + */ + @NotEmpty(message = "商户退款订单号不能为空") + private String merchantRefundId; + + /** + * 用户 IP + */ + private String userIp; +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundRespDTO.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundRespDTO.java new file mode 100644 index 0000000..2e1a6fc --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundRespDTO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.pay.service.order.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +/** + * 退款申请单 Response DTO + */ +@Data +@Accessors(chain = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayRefundRespDTO { + + /** + * 支付退款单编号,自增 + */ + private Long refundId; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/package-info.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/package-info.java new file mode 100644 index 0000000..2cad91e --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.pay.service; diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java new file mode 100755 index 0000000..7ffd52b --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java @@ -0,0 +1,61 @@ +package cn.iocoder.yudao.module.pay.service.refund; + +import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayRefundReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayRefundRespDTO; + +import java.util.List; + +/** + * 退款订单 Service 接口 + * + * @author aquan + */ +public interface PayRefundService { + + /** + * 获得退款订单 + * + * @param id 编号 + * @return 退款订单 + */ + PayRefundDO getRefund(Long id); + + /** + * 获得退款订单分页 + * + * @param pageReqVO 分页查询 + * @return 退款订单分页 + */ + PageResult getRefundPage(PayRefundPageReqVO pageReqVO); + + /** + * 获得退款订单列表, 用于 Excel 导出 + * + * @param exportReqVO 查询条件 + * @return 退款订单列表 + */ + List getRefundList(PayRefundExportReqVO exportReqVO); + + /** + * 提交退款申请 + * + * @param reqDTO 退款申请信息 + * @return 退款申请返回信息 + */ + PayRefundRespDTO submitRefundOrder(PayRefundReqDTO reqDTO); + + /** + * 渠道的退款通知 + * + * @param channelId 渠道编号 + * @param notifyData 通知数据 + * @throws Exception 退款通知异常 + */ + void notifyPayRefund(Long channelId, PayNotifyDataDTO notifyData) throws Exception; + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java new file mode 100755 index 0000000..4e3a151 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java @@ -0,0 +1,261 @@ +package cn.iocoder.yudao.module.pay.service.refund; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; +import cn.iocoder.yudao.framework.pay.core.client.PayClient; +import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; +import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundNotifyDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundUnifiedReqDTO; +import cn.iocoder.yudao.framework.pay.core.client.dto.PayRefundUnifiedRespDTO; +import cn.iocoder.yudao.framework.pay.core.enums.PayNotifyRefundStatusEnum; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants; +import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundTypeEnum; +import cn.iocoder.yudao.module.pay.service.merchant.PayAppService; +import cn.iocoder.yudao.module.pay.service.merchant.PayChannelService; +import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; +import cn.iocoder.yudao.module.pay.service.notify.dto.PayNotifyTaskCreateReqDTO; +import cn.iocoder.yudao.module.pay.service.order.PayOrderExtensionService; +import cn.iocoder.yudao.module.pay.service.order.PayOrderService; +import cn.iocoder.yudao.module.pay.service.order.dto.PayRefundReqDTO; +import cn.iocoder.yudao.module.pay.service.order.dto.PayRefundRespDTO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + * 退款订单 Service 实现类 + * + * @author aquan + */ +@Service +@Slf4j +@Validated +public class PayRefundServiceImpl implements PayRefundService { + + @Resource + private PayClientFactory payClientFactory; + + @Resource + private PayRefundMapper refundMapper; + @Resource + private PayOrderMapper orderMapper; // TODO @jason:需要改成不直接操作 db; + + @Resource + private PayOrderService orderService; + @Resource + private PayOrderExtensionService orderExtensionService; + @Resource + private PayAppService appService; + @Resource + private PayChannelService channelService; + @Resource + private PayNotifyService notifyService; + + @Override + public PayRefundDO getRefund(Long id) { + return refundMapper.selectById(id); + } + + @Override + public PageResult getRefundPage(PayRefundPageReqVO pageReqVO) { + return refundMapper.selectPage(pageReqVO); + } + + @Override + public List getRefundList(PayRefundExportReqVO exportReqVO) { + return refundMapper.selectList(exportReqVO); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public PayRefundRespDTO submitRefundOrder(PayRefundReqDTO req) { + // 获得 PayOrderDO + PayOrderDO order = orderService.getOrder(req.getPayOrderId()); + // 校验订单是否存在 + if (Objects.isNull(order) ) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_NOT_FOUND); + } + // 校验 App + PayAppDO app = appService.validPayApp(order.getAppId()); + // 校验支付渠道是否有效 + PayChannelDO channel = channelService.validPayChannel(order.getChannelId()); + // 校验支付客户端是否正确初始化 + PayClient client = payClientFactory.getPayClient(channel.getId()); + if (client == null) { + log.error("[refund][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND); + } + + // 校验退款的条件 + validatePayRefund(req, order); + // 退款类型 + PayRefundTypeEnum refundType = PayRefundTypeEnum.SOME; + if (Objects.equals(req.getAmount(), order.getAmount())) { + refundType = PayRefundTypeEnum.ALL; + } + PayOrderExtensionDO orderExtensionDO = orderExtensionService.getOrderExtension(order.getSuccessExtensionId()); + PayRefundDO payRefundDO = refundMapper.selectByTradeNoAndMerchantRefundNo(orderExtensionDO.getNo(), req.getMerchantRefundId()); + if(Objects.nonNull(payRefundDO)){ + // 退款订单已经提交过。 + //TODO 校验相同退款单的金额 + // TODO @jason:咱要不封装一个 ObjectUtils.equalsAny + if (Objects.equals(PayRefundStatusEnum.SUCCESS.getStatus(), payRefundDO.getStatus()) + || Objects.equals(PayRefundStatusEnum.CLOSE.getStatus(), payRefundDO.getStatus())) { + //已成功退款 + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_REFUND_SUCCEED); + } + //可以重复提交,保证 退款请求号 一致,由渠道保证幂等 + } else { + // 成功,插入退款单 状态为生成.没有和渠道交互 + // TODO @jason:搞到 convert 里。一些额外的自动,手动 set 下; + payRefundDO = PayRefundDO.builder().channelOrderNo(order.getChannelOrderNo()) + .appId(order.getAppId()) + .channelOrderNo(order.getChannelOrderNo()) + .channelCode(order.getChannelCode()) + .channelId(order.getChannelId()) + .merchantId(order.getMerchantId()) + .orderId(order.getId()) + .merchantRefundNo(req.getMerchantRefundId()) + .notifyUrl(app.getRefundNotifyUrl()) + .payAmount(order.getAmount()) + .refundAmount(req.getAmount()) + .userIp(req.getUserIp()) + .merchantOrderId(order.getMerchantOrderId()) + .tradeNo(orderExtensionDO.getNo()) + .status(PayRefundStatusEnum.CREATE.getStatus()) + .reason(req.getReason()) + .notifyStatus(PayOrderNotifyStatusEnum.NO.getStatus()) + .type(refundType.getStatus()) + .build(); + refundMapper.insert(payRefundDO); + } + // TODO @jason:搞到 convert 里。一些额外的自动,手动 set 下; + PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO(); + unifiedReqDTO.setUserIp(req.getUserIp()) + .setAmount(req.getAmount()) + .setChannelOrderNo(order.getChannelOrderNo()) + .setPayTradeNo(orderExtensionDO.getNo()) + .setMerchantRefundId(req.getMerchantRefundId()) + .setReason(req.getReason()); + // 向渠道发起退款申请 + PayCommonResult refundUnifiedResult = client.unifiedRefund(unifiedReqDTO); + // 检查是否失败,失败抛出业务异常。 + // TODO 渠道的异常记录。 + // TODO @jason:可以先打个 warn log 哈; + refundUnifiedResult.checkError(); + // 成功在 退款回调中处理 + return PayRefundRespDTO.builder().refundId(payRefundDO.getId()).build(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void notifyPayRefund(Long channelId, PayNotifyDataDTO notifyData) { + log.info("[notifyPayRefund][channelId({}) 回调数据({})]", channelId, notifyData.getBody()); + // 校验支付渠道是否有效 + PayChannelDO channel = channelService.validPayChannel(channelId); + // 校验支付客户端是否正确初始化 + PayClient client = payClientFactory.getPayClient(channel.getId()); + if (client == null) { + log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId()); + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND); + } + // 解析渠道退款通知数据, 统一处理 + PayRefundNotifyDTO refundNotify = client.parseRefundNotify(notifyData); + if (Objects.equals(PayNotifyRefundStatusEnum.SUCCESS,refundNotify.getStatus())){ + payRefundSuccess(refundNotify); + } else { + //TODO 支付异常, 支付宝似乎没有支付异常的通知。 + // TODO @jason:那这里可以考虑打个 error logger @芋艿 微信是否存在支付异常通知 + } + } + + private void payRefundSuccess(PayRefundNotifyDTO refundNotify) { + // 校验退款单存在 + PayRefundDO refundDO = refundMapper.selectByTradeNoAndMerchantRefundNo(refundNotify.getTradeNo(), refundNotify.getReqNo()); + if (refundDO == null) { + log.error("[payRefundSuccess][不存在 seqNo 为{} 的支付退款单]", refundNotify.getReqNo()); + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_REFUND_NOT_FOUND); + } + + // 得到已退金额 + PayOrderDO payOrderDO = orderService.getOrder(refundDO.getOrderId()); + Long refundedAmount = payOrderDO.getRefundAmount(); + + PayOrderStatusEnum orderStatus = PayOrderStatusEnum.SUCCESS; + if(Objects.equals(payOrderDO.getAmount(), refundedAmount+ refundDO.getRefundAmount())){ + //支付金额 = 已退金额 + 本次退款金额。 + orderStatus = PayOrderStatusEnum.CLOSED; + } + // 更新支付订单 + PayOrderDO updateOrderDO = new PayOrderDO(); + updateOrderDO.setId(refundDO.getOrderId()) + .setRefundAmount(refundedAmount + refundDO.getRefundAmount()) + .setStatus(orderStatus.getStatus()) + .setRefundTimes(payOrderDO.getRefundTimes() + 1) + .setRefundStatus(refundDO.getType()); + orderMapper.updateById(updateOrderDO); + + // 更新退款订单 + PayRefundDO updateRefundDO = new PayRefundDO(); + updateRefundDO.setId(refundDO.getId()) + .setSuccessTime(refundNotify.getRefundSuccessTime()) + .setChannelRefundNo(refundNotify.getChannelOrderNo()) + .setTradeNo(refundNotify.getTradeNo()) + .setNotifyTime(new Date()) + .setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); + refundMapper.updateById(updateRefundDO); + + // 插入退款通知记录 + // TODO 通知商户成功或者失败. 现在通知似乎没有实现, 只是回调 + notifyService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder() + .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refundDO.getId()).build()); + } + + /** + * 校验是否进行退款 + * @param req 退款申请信息 + * @param order 原始支付订单信息 + */ + private void validatePayRefund(PayRefundReqDTO req, PayOrderDO order) { + // 校验状态,必须是支付状态 + if (!PayOrderStatusEnum.SUCCESS.getStatus().equals(order.getStatus())) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_SUCCESS); + } + // 是否已经全额退款 + if (PayRefundTypeEnum.ALL.getStatus().equals(order.getRefundStatus())) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_REFUND_ALL_REFUNDED); + } + // 校验金额 退款金额不能大于 原定的金额 + if (req.getAmount() + order.getRefundAmount() > order.getAmount()){ + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_REFUND_AMOUNT_EXCEED); + } + // 校验渠道订单号 + if (StrUtil.isEmpty(order.getChannelOrderNo())) { + throw ServiceExceptionUtil.exception(ErrorCodeConstants.PAY_REFUND_CHN_ORDER_NO_IS_NULL); + } + //TODO 退款的期限 退款次数的控制 + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/util/PaySeqUtils.java b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/util/PaySeqUtils.java new file mode 100644 index 0000000..e6409e9 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/main/java/cn/iocoder/yudao/module/pay/util/PaySeqUtils.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.pay.util; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; + +import java.util.Date; +import java.util.concurrent.atomic.AtomicLong; + +/** + * 支付相关编号的生产 + */ +// TODO @jason:需要改造,基于 db; +public class PaySeqUtils { + + private static final AtomicLong REFUND_REQ_NO_SEQ = new AtomicLong(0L); + + private static final AtomicLong MER_REFUND_NO_SEQ = new AtomicLong(0L); + + private static final AtomicLong MER_ORDER_NO_SEQ = new AtomicLong(0L); + + /** + * 生成商户退款单号,用于测试,应该由商户系统生成 + * @return 商户退款单 + */ + public static String genMerchantRefundNo() { + return String.format("%s%s%04d", "MR", + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN), + (int) MER_REFUND_NO_SEQ.getAndIncrement() % 10000); + } + + /** + * 生成退款请求号 + * @return 退款请求号 + */ + public static String genRefundReqNo() { + return String.format("%s%s%04d", "RR", + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN), + (int) REFUND_REQ_NO_SEQ.getAndIncrement() % 10000); + } + + /** + * 生成商户订单编号号 用于测试,应该由商户系统生成 + * @return 商户订单编号 + */ + public static String genMerchantOrderNo() { + return String.format("%s%s%04d", "MO", + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN), + (int) MER_ORDER_NO_SEQ.getAndIncrement() % 10000); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceTest.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceTest.java new file mode 100644 index 0000000..0939ade --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayAppServiceTest.java @@ -0,0 +1,244 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.app.PayAppUpdateReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayAppMapper; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayMerchantMapper; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.Collections; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.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.module.pay.enums.ErrorCodeConstants.*; +import static org.junit.jupiter.api.Assertions.*; + +/** + * {@link PayAppServiceImpl} 的单元测试类 + * + * @author 芋艿 + */ +@Import(PayAppServiceImpl.class) +public class PayAppServiceTest extends BaseDbUnitTest { + + @Resource + private PayAppServiceImpl appService; + + @Resource + private PayAppMapper appMapper; + + @MockBean(name = "payMerchantMapper") + private PayMerchantMapper payMerchantMapper; + + @Test + public void testCreateApp_success() { + // 准备参数 + PayAppCreateReqVO reqVO = randomPojo(PayAppCreateReqVO.class, o -> + o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); + + // 调用 + Long appId = appService.createApp(reqVO); + // 断言 + assertNotNull(appId); + // 校验记录的属性是否正确 + PayAppDO app = appMapper.selectById(appId); + assertPojoEquals(reqVO, app); + } + + @Test + public void testUpdateApp_success() { + // mock 数据 + PayAppDO dbApp = randomPojo(PayAppDO.class, o -> + o.setStatus(CommonStatusEnum.DISABLE.getStatus())); + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> { + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setId(dbApp.getId()); // 设置更新的 ID + }); + + // 调用 + appService.updateApp(reqVO); + // 校验是否更新正确 + PayAppDO app = appMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, app); + } + + @Test + public void testUpdateApp_notExists() { + // 准备参数 + PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o -> + o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); + // 调用, 并断言异常 + assertServiceException(() -> appService.updateApp(reqVO), PAY_APP_NOT_FOUND); + } + + @Test + public void testDeleteApp_success() { + // mock 数据 + PayAppDO dbApp = randomPojo(PayAppDO.class, o -> + o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus()))); + appMapper.insert(dbApp);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbApp.getId(); + + // 调用 + appService.deleteApp(id); + // 校验数据不存在了 + assertNull(appMapper.selectById(id)); + } + + @Test + public void testDeleteApp_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND); + } + + @Test + public void testGetAppPage() { + Long merchantId = 1L; + Long mismatchMerchantId = 2L; + + // mock 数据 + 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.setMerchantId(merchantId); + o.setCreateTime(buildTime(2021,11,20)); + }); + + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 + o.setId(merchantId); + o.setNo("M1008611"); + o.setName("灿哥的杂货铺"); + o.setShortName("灿灿子"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setRemark("灿哥的杂货铺"); + o.setCreateTime(buildTime(2021,11,3)); + }); + + Mockito.when(payMerchantMapper.getMerchantListByName(dbMerchant.getName())) + .thenReturn(Collections.singletonList(dbMerchant)); + + appMapper.insert(dbApp); + // 测试 name 不匹配 + 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"))); + // 测试 merchantId 不匹配 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setMerchantId(mismatchMerchantId))); + // 测试 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.setMerchantName(dbMerchant.getName()); + reqVO.setBeginCreateTime(buildTime(2021,11,19)); + reqVO.setEndCreateTime(buildTime(2021,11,21)); + + // 调用 + PageResult pageResult = appService.getAppPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbApp, pageResult.getList().get(0)); + } + + @Test // TODO 请修改 null 为需要的值 + public void testGetAppList() { + Long merchantId = 1L; + Long mismatchMerchantId = 2L; + + // mock 数据 + 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.setMerchantId(merchantId); + o.setCreateTime(buildTime(2021,11,20)); + }); + + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 + o.setId(merchantId); + o.setNo("M1008611"); + o.setName("灿哥的杂货铺"); + o.setShortName("灿灿子"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setRemark("灿哥的杂货铺"); + o.setCreateTime(buildTime(2021,11,3)); + }); + + Mockito.when(payMerchantMapper.getMerchantListByName(dbMerchant.getName())) + .thenReturn(Collections.singletonList(dbMerchant)); + + appMapper.insert(dbApp); + // 测试 name 不匹配 + 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"))); + // 测试 merchantId 不匹配 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setMerchantId(mismatchMerchantId))); + // 测试 createTime 不匹配 + appMapper.insert(cloneIgnoreId(dbApp, o -> o.setCreateTime(buildTime(2021,12,21)))); + // 准备参数 + PayAppExportReqVO reqVO = new PayAppExportReqVO(); + reqVO.setName("灿灿姐的杂货铺"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setRemark("敏敏姐的小卖铺"); + reqVO.setPayNotifyUrl("https://www.hc.com"); + reqVO.setRefundNotifyUrl("https://www.xm.com"); + reqVO.setMerchantName(dbMerchant.getName()); + reqVO.setBeginCreateTime(buildTime(2021,11,19)); + reqVO.setEndCreateTime(buildTime(2021,11,21)); + + // 调用 + List list = appService.getAppList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbApp, list.get(0)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceTest.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceTest.java new file mode 100644 index 0000000..6397bb4 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayChannelServiceTest.java @@ -0,0 +1,392 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; +import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.channel.PayChannelUpdateReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayChannelDO; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayChannelMapper; +import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest; +import com.alibaba.fastjson.JSON; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.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.module.pay.enums.ErrorCodeConstants.CHANNEL_NOT_EXISTS; +import static org.junit.jupiter.api.Assertions.*; + +@Import({PayChannelServiceImpl.class}) +public class PayChannelServiceTest extends BaseDbUnitTest { + + @Resource + private PayChannelServiceImpl channelService; + + @Resource + private PayChannelMapper channelMapper; + + @Test + public void testCreateWechatVersion2Channel_success() { + // 准备参数 + + WXPayClientConfig v2Config = getV2Config(); + PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { + o.setCode(PayChannelEnum.WX_PUB.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setConfig(JSON.toJSONString(v2Config)); + }); + + // 调用 + Long channelId = channelService.createChannel(reqVO); + // 断言 + assertNotNull(channelId); + // 校验记录的属性是否正确 + PayChannelDO channel = channelMapper.selectById(channelId); + assertPojoEquals(reqVO, channel, "config"); + // 关于config 对象应该拿出来重新对比 + assertPojoEquals(v2Config, channel.getConfig()); + } + + @Test + public void testCreateWechatVersion3Channel_success() { + // 准备参数 + WXPayClientConfig v3Config = getV3Config(); + PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { + o.setCode(PayChannelEnum.WX_PUB.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setConfig(JSON.toJSONString(v3Config)); + }); + + // 调用 + Long channelId = channelService.createChannel(reqVO); + // 断言 + assertNotNull(channelId); + // 校验记录的属性是否正确 + PayChannelDO channel = channelMapper.selectById(channelId); + assertPojoEquals(reqVO, channel, "config"); + // 关于config 对象应该拿出来重新对比 + assertPojoEquals(v3Config, channel.getConfig()); + } + + @Test + public void testCreateAliPayPublicKeyChannel_success() { + // 准备参数 + + AlipayPayClientConfig payClientConfig = getPublicKeyConfig(); + PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setConfig(JSON.toJSONString(payClientConfig)); + }); + + // 调用 + Long channelId = channelService.createChannel(reqVO); + // 断言 + assertNotNull(channelId); + // 校验记录的属性是否正确 + PayChannelDO channel = channelMapper.selectById(channelId); + assertPojoEquals(reqVO, channel, "config"); + // 关于config 对象应该拿出来重新对比 + assertPojoEquals(payClientConfig, channel.getConfig()); + + } + + @Test + public void testCreateAliPayCertificateChannel_success() { + // 准备参数 + + AlipayPayClientConfig payClientConfig = getCertificateConfig(); + PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> { + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setConfig(JSON.toJSONString(payClientConfig)); + }); + + // 调用 + Long channelId = channelService.createChannel(reqVO); + // 断言 + assertNotNull(channelId); + // 校验记录的属性是否正确 + PayChannelDO channel = channelMapper.selectById(channelId); + assertPojoEquals(reqVO, channel, "config"); + // 关于config 对象应该拿出来重新对比 + assertPojoEquals(payClientConfig, channel.getConfig()); + } + + @Test + public void testUpdateChannel_success() { + // mock 数据 + AlipayPayClientConfig payClientConfig = getCertificateConfig(); + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setConfig(payClientConfig); + }); + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 + // 准备参数 + AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig(); + PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> { + o.setCode(dbChannel.getCode()); + o.setStatus(dbChannel.getStatus()); + o.setConfig(JSON.toJSONString(payClientPublicKeyConfig)); + o.setId(dbChannel.getId()); // 设置更新的 ID + }); + + // 调用 + channelService.updateChannel(reqVO); + // 校验是否更新正确 + PayChannelDO channel = channelMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, channel, "config"); + assertPojoEquals(payClientPublicKeyConfig, channel.getConfig()); + } + + @Test + public void testUpdateChannel_notExists() { + // 准备参数 + AlipayPayClientConfig payClientPublicKeyConfig = getPublicKeyConfig(); + PayChannelUpdateReqVO reqVO = randomPojo(PayChannelUpdateReqVO.class, o -> { + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setConfig(JSON.toJSONString(payClientPublicKeyConfig)); + }); + + // 调用, 并断言异常 + assertServiceException(() -> channelService.updateChannel(reqVO), CHANNEL_NOT_EXISTS); + } + + @Test + public void testDeleteChannel_success() { + // mock 数据 + AlipayPayClientConfig payClientConfig = getCertificateConfig(); + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setConfig(payClientConfig); + }); + channelMapper.insert(dbChannel);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbChannel.getId(); + + // 调用 + channelService.deleteChannel(id); + // 校验数据不存在了 + assertNull(channelMapper.selectById(id)); + } + + @Test + public void testDeleteChannel_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> channelService.deleteChannel(id), CHANNEL_NOT_EXISTS); + } + + @Test // TODO 请修改 null 为需要的值 + public void testGetChannelPage() { + // mock 数据 + AlipayPayClientConfig payClientConfig = getCertificateConfig(); + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setRemark("灿灿子的支付渠道"); + o.setFeeRate(0.03); + o.setMerchantId(1L); + o.setAppId(1L); + o.setConfig(payClientConfig); + o.setCreateTime(buildTime(2021,11,20)); + }); + channelMapper.insert(dbChannel); + // 执行拷贝的时候会出现异常,所以在插入后要重置为null 后续在写入新的 + dbChannel.setConfig(null); + // 测试 code 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setCode(PayChannelEnum.WX_PUB.getCode()); + })); + // 测试 status 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setStatus(CommonStatusEnum.DISABLE.getStatus()); + })); + // 测试 remark 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o ->{ + o.setConfig(payClientConfig); + o.setRemark("敏敏子的渠道"); + })); + // 测试 feeRate 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setFeeRate(1.23); + })); + // 测试 merchantId 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setMerchantId(2L); + })); + // 测试 appId 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setAppId(2L); + })); + // 测试 createTime 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setCreateTime(buildTime(2021, 10, 20)); + })); + // 准备参数 + PayChannelPageReqVO reqVO = new PayChannelPageReqVO(); + reqVO.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setRemark("灿灿子的支付渠道"); + reqVO.setFeeRate(0.03); + reqVO.setMerchantId(1L); + reqVO.setAppId(1L); + reqVO.setConfig(JSON.toJSONString(payClientConfig)); + reqVO.setBeginCreateTime(buildTime(2021,11,19)); + reqVO.setEndCreateTime(buildTime(2021,11,21)); + + // 调用 + PageResult pageResult = channelService.getChannelPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbChannel, pageResult.getList().get(0), "config"); + assertPojoEquals(payClientConfig, pageResult.getList().get(0).getConfig()); + + } + + @Test + public void testGetChannelList() { + // mock 数据 + AlipayPayClientConfig payClientConfig = getCertificateConfig(); + PayChannelDO dbChannel = randomPojo(PayChannelDO.class, o -> { // 等会查询到 + o.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setRemark("灿灿子的支付渠道"); + o.setFeeRate(0.03); + o.setMerchantId(1L); + o.setAppId(1L); + o.setConfig(payClientConfig); + o.setCreateTime(buildTime(2021,11,20)); + }); + channelMapper.insert(dbChannel); + // 执行拷贝的时候会出现异常,所以在插入后要重置为null 后续在写入新的 + dbChannel.setConfig(null); + // 测试 code 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setCode(PayChannelEnum.WX_PUB.getCode()); + })); + // 测试 status 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setStatus(CommonStatusEnum.DISABLE.getStatus()); + })); + // 测试 remark 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o ->{ + o.setConfig(payClientConfig); + o.setRemark("敏敏子的渠道"); + })); + // 测试 feeRate 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setFeeRate(1.23); + })); + // 测试 merchantId 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setMerchantId(2L); + })); + // 测试 appId 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setAppId(2L); + })); + // 测试 createTime 不匹配 + channelMapper.insert(cloneIgnoreId(dbChannel, o -> { + o.setConfig(payClientConfig); + o.setCreateTime(buildTime(2021, 10, 20)); + })); + // 准备参数 + PayChannelExportReqVO reqVO = new PayChannelExportReqVO(); + reqVO.setCode(PayChannelEnum.ALIPAY_APP.getCode()); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setRemark("灿灿子的支付渠道"); + reqVO.setFeeRate(0.03); + reqVO.setMerchantId(1L); + reqVO.setAppId(1L); + reqVO.setConfig(JSON.toJSONString(payClientConfig)); + reqVO.setBeginCreateTime(buildTime(2021,11,19)); + reqVO.setEndCreateTime(buildTime(2021,11,21)); + + // 调用 + List list = channelService.getChannelList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbChannel, list.get(0), "config"); + assertPojoEquals(payClientConfig, list.get(0).getConfig()); + } + + public WXPayClientConfig getV2Config() { + return new WXPayClientConfig() + .setAppId("APP00001") + .setMchId("MCH00001") + .setApiVersion(WXPayClientConfig.API_VERSION_V2) + .setMchKey("dsa1d5s6a1d6sa16d1sa56d15a61das6") + .setApiV3Key("") + .setPrivateCertContent("") + .setPrivateKeyContent(""); + } + + public WXPayClientConfig getV3Config() { + return new WXPayClientConfig() + .setAppId("APP00001") + .setMchId("MCH00001") + .setApiVersion(WXPayClientConfig.API_VERSION_V3) + .setMchKey("") + .setApiV3Key("sdadasdsadadsa") + .setPrivateKeyContent("dsa445das415d15asd16ad156as") + .setPrivateCertContent("dsadasd45asd4s5a"); + + } + + public AlipayPayClientConfig getPublicKeyConfig() { + return new AlipayPayClientConfig() + .setServerUrl(AlipayPayClientConfig.SERVER_URL_PROD) + .setAppId("APP00001") + .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) + .setMode(AlipayPayClientConfig.MODE_PUBLIC_KEY) + .setPrivateKey("13131321312") + .setAlipayPublicKey("13321321321") + .setAppCertContent("") + .setAlipayPublicCertContent("") + .setRootCertContent(""); + } + + public AlipayPayClientConfig getCertificateConfig() { + return new AlipayPayClientConfig() + .setServerUrl(AlipayPayClientConfig.SERVER_URL_PROD) + .setAppId("APP00001") + .setSignType(AlipayPayClientConfig.SIGN_TYPE_DEFAULT) + .setMode(AlipayPayClientConfig.MODE_CERTIFICATE) + .setPrivateKey("") + .setAlipayPublicKey("") + .setAppCertContent("13321321321sda") + .setAlipayPublicCertContent("13321321321aqeqw") + .setRootCertContent("13321321321dsad"); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceTest.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceTest.java new file mode 100644 index 0000000..08d0970 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/merchant/PayMerchantServiceTest.java @@ -0,0 +1,192 @@ +package cn.iocoder.yudao.module.pay.service.merchant; + +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantCreateReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantPageReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.merchant.vo.merchant.PayMerchantUpdateReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.merchant.PayMerchantDO; +import cn.iocoder.yudao.module.pay.dal.mysql.merchant.PayMerchantMapper; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.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.module.pay.enums.ErrorCodeConstants.*; +import static org.junit.jupiter.api.Assertions.*; + +/** +* {@link PayMerchantServiceImpl} 的单元测试类 +* +* @author aquan +*/ +@Import(PayMerchantServiceImpl.class) +public class PayMerchantServiceTest extends BaseDbUnitTest { + + @Resource + private PayMerchantServiceImpl merchantService; + + @Resource + private PayMerchantMapper merchantMapper; + + @Test + public void testCreateMerchant_success() { + // 准备参数 + PayMerchantCreateReqVO reqVO = randomPojo(PayMerchantCreateReqVO.class,o -> + o.setStatus(RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())); + + // 调用 + Long merchantId = merchantService.createMerchant(reqVO); + // 断言 + assertNotNull(merchantId); + // 校验记录的属性是否正确 + PayMerchantDO merchant = merchantMapper.selectById(merchantId); + assertPojoEquals(reqVO, merchant); + } + + @Test + public void testUpdateMerchant_success() { + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> + o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据 + // 准备参数 + PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class, o -> { + o.setId(dbMerchant.getId()); // 设置更新的 ID + o.setStatus(CommonStatusEnum.DISABLE.getStatus()); + }); + + // 调用 + merchantService.updateMerchant(reqVO); + // 校验是否更新正确 + PayMerchantDO merchant = merchantMapper.selectById(reqVO.getId()); // 获取最新的 + assertPojoEquals(reqVO, merchant); + } + + @Test + public void testUpdateMerchant_notExists() { + // 准备参数 + PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class); + + // 调用, 并断言异常 + assertServiceException(() -> merchantService.updateMerchant(reqVO), PAY_MERCHANT_NOT_EXISTS); + } + + @Test + public void testDeleteMerchant_success() { + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, + o-> o.setStatus(CommonStatusEnum.ENABLE.getStatus())); + merchantMapper.insert(dbMerchant);// @Sql: 先插入出一条存在的数据 + // 准备参数 + Long id = dbMerchant.getId(); + + // 调用 + merchantService.deleteMerchant(id); + // 校验数据不存在了 + assertNull(merchantMapper.selectById(id)); + } + + @Test + public void testDeleteMerchant_notExists() { + // 准备参数 + Long id = randomLongId(); + + // 调用, 并断言异常 + assertServiceException(() -> merchantService.deleteMerchant(id), PAY_MERCHANT_NOT_EXISTS); + } + + @Test + public void testGetMerchantPage() { + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 + o.setNo("M1008611"); + o.setName("灿哥的杂货铺"); + o.setShortName("灿灿子"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setRemark("灿哥的杂货铺"); + o.setCreateTime(buildTime(2021,11,3)); + }); + merchantMapper.insert(dbMerchant); + // 测试 no 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setNo("M200000"))); + // 测试 name 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setName("斌哥的杂货铺"))); + // 测试 shortName 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setShortName("斌斌子"))); + // 测试 status 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 remark 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setRemark("斌哥的杂货铺"))); + // 测试 createTime 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4)))); + // 准备参数 + PayMerchantPageReqVO reqVO = new PayMerchantPageReqVO(); + reqVO.setNo("M1008611"); + reqVO.setName("灿哥的杂货铺"); + reqVO.setShortName("灿灿子"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setRemark("灿哥的杂货铺"); + reqVO.setBeginCreateTime(buildTime(2021,11,2)); + reqVO.setEndCreateTime(buildTime(2021,11,4)); + + // 调用 + PageResult pageResult = merchantService.getMerchantPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbMerchant, pageResult.getList().get(0)); + } + + @Test + public void testGetMerchantList() { + // mock 数据 + PayMerchantDO dbMerchant = randomPojo(PayMerchantDO.class, o -> { // 等会查询到 + o.setNo("M1008611"); + o.setName("灿哥的杂货铺"); + o.setShortName("灿灿子"); + o.setStatus(CommonStatusEnum.ENABLE.getStatus()); + o.setRemark("灿哥的杂货铺"); + o.setCreateTime(buildTime(2021,11,3)); + }); + merchantMapper.insert(dbMerchant); + // 测试 no 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setNo("M200000"))); + // 测试 name 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setName("斌哥的杂货铺"))); + // 测试 shortName 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setShortName("斌斌子"))); + // 测试 status 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus()))); + // 测试 remark 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setRemark("斌哥的杂货铺"))); + // 测试 createTime 不匹配 + merchantMapper.insert(cloneIgnoreId(dbMerchant, o -> o.setCreateTime(buildTime(2022,12,4)))); + // 准备参数 + PayMerchantExportReqVO reqVO = new PayMerchantExportReqVO(); + reqVO.setNo("M1008611"); + reqVO.setName("灿哥的杂货铺"); + reqVO.setShortName("灿灿子"); + reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); + reqVO.setRemark("灿哥的杂货铺"); + reqVO.setBeginCreateTime(buildTime(2021,11,2)); + reqVO.setEndCreateTime(buildTime(2021,11,4)); + + // 调用 + List list = merchantService.getMerchantList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbMerchant, list.get(0)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java new file mode 100755 index 0000000..e3ac739 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java @@ -0,0 +1,195 @@ +package cn.iocoder.yudao.module.pay.service.order; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.RandomUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderPageReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; +import cn.iocoder.yudao.module.pay.dal.mysql.order.PayOrderMapper; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundTypeEnum; +import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; + +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.RandomUtils.randomPojo; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * {@link PayOrderServiceImpl} 的单元测试类 + * + * @author 芋艿 + */ +@Import(PayOrderServiceImpl.class) +public class PayOrderServiceTest extends BaseDbUnitTest { + + @Resource + private PayOrderServiceImpl orderService; + + @Resource + private PayOrderMapper orderMapper; + + public String generateNo() { + return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomInt(100000, 999999); + } + + @Test + public void testGetOrderPage() { + + String merchantOrderId = generateNo(); + String channelOrderId = generateNo(); + + // mock 数据 + PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到 + o.setMerchantId(1L); + o.setAppId(1L); + o.setChannelId(1L); + o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + o.setMerchantOrderId(merchantOrderId); + o.setSubject("灿灿子的炸弹猫"); + o.setBody("斌斌子送给灿灿子的炸弹猫"); + o.setNotifyUrl("https://hc.com/lbh"); + o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); + o.setAmount(10000L); + o.setChannelFeeRate(0.01); + o.setChannelFeeAmount(1L); + o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); + o.setUserIp("127.0.0.1"); + o.setCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); + o.setExpireTime(DateUtils.buildTime(2018, 1, 1, 10, 30, 0)); + o.setSuccessTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 2)); + o.setNotifyTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15)); + o.setSuccessExtensionId(1L); + o.setRefundStatus(PayRefundTypeEnum.NO.getStatus()); + o.setRefundTimes(0); + o.setRefundAmount(0L); + o.setChannelUserId("1008611"); + o.setChannelOrderNo(channelOrderId); + o.setUpdateTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15)); + }); + orderMapper.insert(dbOrder); + // 测试 merchantId 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantId(2L))); + // 测试 appId 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L))); + // 测试 channelId 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L))); + // 测试 channelCode 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); + // 测试 merchantOrderId 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(generateNo()))); + // 测试 notifyStatus 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); + // 测试 status 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus()))); + // 测试 refundStatus 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayRefundTypeEnum.ALL.getStatus()))); + // 测试 createTime 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(DateUtils.buildTime(2019, 1, 1, 10, 10, + 1)))); + // 准备参数 + PayOrderPageReqVO reqVO = new PayOrderPageReqVO(); + reqVO.setMerchantId(1L); + reqVO.setAppId(1L); + reqVO.setChannelId(1L); + reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + reqVO.setMerchantOrderId(merchantOrderId); + reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); + reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); + reqVO.setRefundStatus(PayRefundTypeEnum.NO.getStatus()); + reqVO.setBeginCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); + reqVO.setEndCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); + + // 调用 + PageResult pageResult = orderService.getOrderPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbOrder, pageResult.getList().get(0)); + // assertEquals(0, dbOrder.getUpdateTime().compareTo(pageResult.getList().get(0).getUpdateTime())); + } + + @Test + public void testGetOrderList() { + // mock 数据 + String merchantOrderId = generateNo(); + String channelOrderId = generateNo(); + PayOrderDO dbOrder = randomPojo(PayOrderDO.class, o -> { // 等会查询到 + o.setMerchantId(1L); + o.setAppId(1L); + o.setChannelId(1L); + o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + o.setMerchantOrderId(merchantOrderId); + o.setSubject("灿灿子的炸弹猫"); + o.setBody("斌斌子送给灿灿子的炸弹猫"); + o.setNotifyUrl("https://hc.com/lbh"); + o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); + o.setAmount(10000L); + o.setChannelFeeRate(0.01); + o.setChannelFeeAmount(1L); + o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); + o.setUserIp("127.0.0.1"); + o.setCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); + o.setExpireTime(DateUtils.buildTime(2018, 1, 1, 10, 30, 0)); + o.setSuccessTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 2)); + o.setNotifyTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15)); + o.setSuccessExtensionId(1L); + o.setRefundStatus(PayRefundTypeEnum.NO.getStatus()); + o.setRefundTimes(0); + o.setRefundAmount(0L); + o.setChannelUserId("1008611"); + o.setChannelOrderNo(channelOrderId); + o.setUpdateTime(DateUtils.buildTime(2018, 1, 1, 10, 10, 15)); + + }); + orderMapper.insert(dbOrder); + // 测试 merchantId 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantId(2L))); + // 测试 appId 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setAppId(2L))); + // 测试 channelId 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelId(2L))); + // 测试 channelCode 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); + // 测试 merchantOrderId 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setMerchantOrderId(generateNo()))); + // 测试 notifyStatus 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); + // 测试 status 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setStatus(PayOrderStatusEnum.CLOSED.getStatus()))); + // 测试 refundStatus 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setRefundStatus(PayRefundTypeEnum.ALL.getStatus()))); + // 测试 createTime 不匹配 + orderMapper.insert(cloneIgnoreId(dbOrder, o -> o.setCreateTime(DateUtils.buildTime(2019, 1, 1, 10, 10, + 1)))); + // 准备参数 + PayOrderExportReqVO reqVO = new PayOrderExportReqVO(); + reqVO.setMerchantId(1L); + reqVO.setAppId(1L); + reqVO.setChannelId(1L); + reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + reqVO.setMerchantOrderId(merchantOrderId); + reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); + reqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()); + reqVO.setRefundStatus(PayRefundTypeEnum.NO.getStatus()); + reqVO.setBeginCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); + reqVO.setEndCreateTime(DateUtils.buildTime(2018, 1, 1, 10, 1, 0)); + + // 调用 + List list = orderService.getOrderList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbOrder, list.get(0)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/package-info.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/package-info.java new file mode 100644 index 0000000..2cad91e --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.pay.service; diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java new file mode 100755 index 0000000..1d91732 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java @@ -0,0 +1,182 @@ +package cn.iocoder.yudao.module.pay.service.refund; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundExportReqVO; +import cn.iocoder.yudao.module.pay.controller.admin.refund.vo.PayRefundPageReqVO; +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; +import cn.iocoder.yudao.module.pay.dal.mysql.refund.PayRefundMapper; +import cn.iocoder.yudao.module.pay.enums.order.PayOrderNotifyStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; +import cn.iocoder.yudao.module.pay.enums.refund.PayRefundTypeEnum; +import cn.iocoder.yudao.module.pay.test.BaseDbUnitTest; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.List; + +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.RandomUtils.randomPojo; +import static org.junit.jupiter.api.Assertions.assertEquals; + + +/** + * {@link PayRefundServiceImpl} 的单元测试类 + * + * @author aquan + */ +@Import(PayRefundServiceImpl.class) +public class PayRefundServiceTest extends BaseDbUnitTest { + + @Resource + private PayRefundServiceImpl refundService; + + @Resource + private PayRefundMapper refundMapper; + + + @Test + public void testGetRefundPage() { + // mock 数据 + PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到 + o.setMerchantId(1L); + o.setAppId(1L); + o.setChannelId(1L); + o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + o.setOrderId(1L); + o.setTradeNo("OT0000001"); + o.setMerchantOrderId("MOT0000001"); + o.setMerchantRefundNo("MRF0000001"); + o.setNotifyUrl("https://www.cancanzi.com"); + o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); + o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); + o.setType(PayRefundTypeEnum.SOME.getStatus()); + o.setPayAmount(100L); + o.setRefundAmount(500L); + o.setReason("就是想退款了,你有意见吗"); + o.setUserIp("127.0.0.1"); + o.setChannelOrderNo("CH0000001"); + o.setChannelRefundNo("CHR0000001"); + o.setChannelErrorCode(""); + o.setChannelErrorMsg(""); + o.setChannelExtras(""); + o.setExpireTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 30)); + o.setSuccessTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 15)); + o.setNotifyTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 20)); + o.setCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10)); + o.setUpdateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 35)); + }); + refundMapper.insert(dbRefund); + // 测试 merchantId 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantId(2L))); + // 测试 appId 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L))); + // 测试 channelCode 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); + // 测试 merchantRefundNo 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundNo("MRF1111112"))); + // 测试 notifyStatus 不匹配 + refundMapper.insert( + cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); + // 测试 status 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.CLOSE.getStatus()))); + // 测试 type 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayRefundTypeEnum.ALL.getStatus()))); + // 测试 createTime 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> + o.setCreateTime(DateUtils.buildTime(2022, 1, 1, 10, 10, 10)))); + // 准备参数 + PayRefundPageReqVO reqVO = new PayRefundPageReqVO(); + reqVO.setMerchantId(1L); + reqVO.setAppId(1L); + reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + reqVO.setMerchantRefundNo("MRF0000001"); + reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); + reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); + reqVO.setType(PayRefundTypeEnum.SOME.getStatus()); + reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10)); + reqVO.setEndCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 12)); + + + // 调用 + PageResult pageResult = refundService.getRefundPage(reqVO); + // 断言 + assertEquals(1, pageResult.getTotal()); + assertEquals(1, pageResult.getList().size()); + assertPojoEquals(dbRefund, pageResult.getList().get(0)); + } + + @Test + public void testGetRefundList() { + // mock 数据 + PayRefundDO dbRefund = randomPojo(PayRefundDO.class, o -> { // 等会查询到 + o.setMerchantId(1L); + o.setAppId(1L); + o.setChannelId(1L); + o.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + o.setOrderId(1L); + o.setTradeNo("OT0000001"); + o.setMerchantOrderId("MOT0000001"); + o.setMerchantRefundNo("MRF0000001"); + o.setNotifyUrl("https://www.cancanzi.com"); + o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); + o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); + o.setType(PayRefundTypeEnum.SOME.getStatus()); + o.setPayAmount(100L); + o.setRefundAmount(500L); + o.setReason("就是想退款了,你有意见吗"); + o.setUserIp("127.0.0.1"); + o.setChannelOrderNo("CH0000001"); + o.setChannelRefundNo("CHR0000001"); + o.setChannelErrorCode(""); + o.setChannelErrorMsg(""); + o.setChannelExtras(""); + o.setExpireTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 30)); + o.setSuccessTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 15)); + o.setNotifyTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 20)); + o.setCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10)); + o.setUpdateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 35)); + }); + refundMapper.insert(dbRefund); + // 测试 merchantId 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantId(2L))); + // 测试 appId 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setAppId(2L))); + // 测试 channelCode 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setChannelCode(PayChannelEnum.ALIPAY_APP.getCode()))); + // 测试 merchantRefundNo 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setMerchantRefundNo("MRF1111112"))); + // 测试 notifyStatus 不匹配 + refundMapper.insert( + cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); + // 测试 status 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.CLOSE.getStatus()))); + // 测试 type 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayRefundTypeEnum.ALL.getStatus()))); + // 测试 createTime 不匹配 + refundMapper.insert(cloneIgnoreId(dbRefund, o -> + o.setCreateTime(DateUtils.buildTime(2022, 1, 1, 10, 10, 10)))); + + // 准备参数 + PayRefundExportReqVO reqVO = new PayRefundExportReqVO(); + reqVO.setMerchantId(1L); + reqVO.setAppId(1L); + reqVO.setChannelCode(PayChannelEnum.WX_PUB.getCode()); + reqVO.setMerchantRefundNo("MRF0000001"); + reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); + reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); + reqVO.setType(PayRefundTypeEnum.SOME.getStatus()); + reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 10)); + reqVO.setEndCreateTime(DateUtils.buildTime(2021, 1, 1, 10, 10, 12)); + + // 调用 + List list = refundService.getRefundList(reqVO); + // 断言 + assertEquals(1, list.size()); + assertPojoEquals(dbRefund, list.get(0)); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbAndRedisUnitTest.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbAndRedisUnitTest.java new file mode 100644 index 0000000..1c6d327 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbAndRedisUnitTest.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.pay.test; + +import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; +import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; +import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; +import org.redisson.spring.starter.RedissonAutoConfiguration; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; + +/** + * 依赖内存 DB + Redis 的单元测试 + * + * 相比 {@link BaseDbUnitTest} 来说,额外增加了内存 Redis + * + * @author 芋道源码 + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisUnitTest.Application.class) +@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 +@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB +public class BaseDbAndRedisUnitTest { + + @Import({ + // DB 配置类 + YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类 + DataSourceAutoConfiguration.class, // Spring DB 自动配置类 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 + DruidDataSourceAutoConfigure.class, // Druid 自动配置类 + // MyBatis 配置类 + YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类 + MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 + // Redis 配置类 + RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer + RedisAutoConfiguration.class, // Spring Redis 自动配置类 + YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类 + RedissonAutoConfiguration.class, // Redisson 自动高配置类 + }) + public static class Application { + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbUnitTest.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbUnitTest.java new file mode 100644 index 0000000..27affbf --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseDbUnitTest.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.pay.test; + +import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration; +import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration; +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.jdbc.Sql; + +/** + * 依赖内存 DB 的单元测试 + * + * 注意,Service 层同样适用。对于 Service 层的单元测试,我们针对自己模块的 Mapper 走的是 H2 内存数据库,针对别的模块的 Service 走的是 Mock 方法 + * + * @author 芋道源码 + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbUnitTest.Application.class) +@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 +@Sql(scripts = "/sql/clean.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) // 每个单元测试结束后,清理 DB +public class BaseDbUnitTest { + + @Import({ + // DB 配置类 + YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类 + DataSourceAutoConfiguration.class, // Spring DB 自动配置类 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类 + DruidDataSourceAutoConfigure.class, // Druid 自动配置类 + // MyBatis 配置类 + YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类 + MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类 + }) + public static class Application { + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseRedisUnitTest.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseRedisUnitTest.java new file mode 100644 index 0000000..11933c9 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/BaseRedisUnitTest.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.pay.test; + +import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration; +import org.redisson.spring.starter.RedissonAutoConfiguration; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ActiveProfiles; + +/** + * 依赖内存 Redis 的单元测试 + * + * 相比 {@link BaseDbUnitTest} 来说,从内存 DB 改成了内存 Redis + * + * @author 芋道源码 + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseRedisUnitTest.Application.class) +@ActiveProfiles("unit-test") // 设置使用 application-unit-test 配置文件 +public class BaseRedisUnitTest { + + @Import({ + // Redis 配置类 + RedisTestConfiguration.class, // Redis 测试配置类,用于启动 RedisServer + RedisAutoConfiguration.class, // Spring Redis 自动配置类 + YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类 + RedissonAutoConfiguration.class, // Redisson 自动高配置类 + }) + public static class Application { + } + +} diff --git a/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/RedisTestConfiguration.java b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/RedisTestConfiguration.java new file mode 100644 index 0000000..c874212 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-impl/src/test/java/cn/iocoder/yudao/module/pay/test/RedisTestConfiguration.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.pay.test; + +import com.github.fppt.jedismock.RedisServer; +import org.springframework.boot.autoconfigure.data.redis.RedisProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; + +import java.io.IOException; + +@Configuration(proxyBeanMethods = false) +@Lazy(false) // 禁止延迟加载 +@EnableConfigurationProperties(RedisProperties.class) +public class RedisTestConfiguration { + + /** + * 创建模拟的 Redis Server 服务器 + */ + @Bean + public RedisServer redisServer(RedisProperties properties) throws IOException { + RedisServer redisServer = new RedisServer(properties.getPort()); + // TODO 芋艿:一次执行多个单元测试时,貌似创建多个 spring 容器,导致不进行 stop。这样,就导致端口被占用,无法启动。。。 + try { + redisServer.start(); + } catch (Exception ignore) {} + return redisServer; + } + +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java index 9b73264..ab6d1b3 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/DictTypeConstants.java @@ -20,31 +20,6 @@ public interface DictTypeConstants { String SMS_SEND_STATUS = "sys_sms_send_status"; // 短信发送状态 String SMS_RECEIVE_STATUS = "sys_sms_receive_status"; // 短信接收状态 - /** - * 支付-订单-订单状态 - */ - String PAY_ORDER_STATUS = "pay_order_status"; - - /** - * 支付-订单-订单回调商户状态 - */ - String PAY_ORDER_NOTIFY_STATUS = "pay_order_notify_status"; - - /** - * 支付-订单-订单退款状态 - */ - String PAY_ORDER_REFUND_STATUS = "pay_order_refund_status"; - - /** - * 支付-退款订单-退款状态 - */ - String PAY_REFUND_ORDER_STATUS = "pay_refund_order_status"; - - /** - * 支付-退款订单-退款类别 - */ - String PAY_REFUND_ORDER_TYPE = "pay_refund_order_type"; - String BPM_TASK_ASSIGN_RULE_TYPE = "bpm_task_assign_rule_type"; // 任务分配规则类型 String BPM_TASK_ASSIGN_SCRIPT = "bpm_task_assign_script"; // 任务分配自定义脚本 diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java deleted file mode 100644 index fb022b1..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayOrderController.java +++ /dev/null @@ -1,122 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.pay.controller.order; - -import cn.hutool.core.bean.BeanUtil; -import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayOrderCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitRespDTO; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.pay.core.client.PayClient; -import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; -import cn.iocoder.yudao.framework.pay.core.client.dto.PayNotifyDataDTO; -import cn.iocoder.yudao.userserver.modules.pay.controller.order.vo.PayOrderSubmitReqVO; -import cn.iocoder.yudao.userserver.modules.pay.controller.order.vo.PayOrderSubmitRespVO; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import java.util.Map; - -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_CHANNEL_CLIENT_NOT_FOUND; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; - -@Api(tags = "支付订单") -@RestController -@RequestMapping("/pay/order") -@Validated -@Slf4j -public class PayOrderController { - - @Resource - private PayOrderCoreService payOrderCoreService; - @Resource - private PayRefundCoreService payRefundCoreService; - - @Resource - private PayClientFactory payClientFactory; - - - @PostMapping("/submit") - @ApiOperation("提交支付订单") -// @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好 - public CommonResult submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) { - // 获得订单 - PayOrderDO payOrder = payOrderCoreService.getPayOrder(reqVO.getId()); - - // 提交支付 - PayOrderSubmitReqDTO reqDTO = new PayOrderSubmitReqDTO(); - BeanUtil.copyProperties(reqVO, reqDTO, false); - reqDTO.setUserIp(getClientIP()); - reqDTO.setAppId(payOrder.getAppId()); - PayOrderSubmitRespDTO respDTO = payOrderCoreService.submitPayOrder(reqDTO); - - // 拼接返回 - return success(PayOrderSubmitRespVO.builder().invokeResponse(respDTO.getInvokeResponse()).build()); - } - - // ========== 支付渠道的回调 ========== - //TODO 芋道源码 换成了统一的地址了 /notify/{channelId},测试通过可以删除 - @PostMapping("/notify/wx-pub/{channelId}") - @ApiOperation("通知微信公众号支付的结果") - public String notifyWxPayOrder(@PathVariable("channelId") Long channelId, - @RequestBody String xmlData) throws Exception { - payOrderCoreService.notifyPayOrder(channelId, PayNotifyDataDTO.builder().body(xmlData).build()); - return "success"; - } - - /** - * 统一的跳转页面, 支付宝跳转参数说明 - * https://opendocs.alipay.com/open/203/105285#%E5%89%8D%E5%8F%B0%E5%9B%9E%E8%B7%B3%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E - * @param channelId 渠道id - * @return 返回跳转页面 - */ - @GetMapping(value = "/return/{channelId}") - @ApiOperation("渠道统一的支付成功返回地址") - public String returnAliPayOrder(@PathVariable("channelId") Long channelId, @RequestParam Map params){ - //TODO 可以根据渠道和 app_id 返回不同的页面 - log.info("app_id is {}", params.get("app_id")); - return String.format("渠道[%s]支付成功", channelId); - } - - /** - * 统一的渠道支付回调,支付宝的退款回调 - * - * @param channelId 渠道编号 - * @param params form 参数 - * @param originData http request body - * @return 成功返回 "success" - */ - @PostMapping(value = "/notify/{channelId}") - @ApiOperation("渠道统一的支付成功,或退款成功 通知url") - public String notifyChannelPay(@PathVariable("channelId") Long channelId, - @RequestParam Map params, - @RequestBody String originData) throws Exception { - // 校验支付渠道是否存在 - PayClient payClient = payClientFactory.getPayClient(channelId); - if (payClient == null) { - log.error("[notifyPayOrder][渠道编号({}) 找不到对应的支付客户端]", channelId); - throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND); - } - - // 校验通知数据是否合法 - PayNotifyDataDTO notifyData = PayNotifyDataDTO.builder().params(params).body(originData).build(); - payClient.verifyNotifyData(notifyData); - - // 如果是退款,则发起退款通知 - if (payClient.isRefundNotify(notifyData)) { - payRefundCoreService.notifyPayRefund(channelId, PayNotifyDataDTO.builder().params(params).body(originData).build()); - return "success"; - } - - // 如果非退款,则发起支付通知 - payOrderCoreService.notifyPayOrder(channelId, PayNotifyDataDTO.builder().params(params).body(originData).build()); - return "success"; - } - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java deleted file mode 100644 index ba62bdd..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/PayRefundController.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.pay.controller.order; - -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.PayRefundCoreService; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.util.PaySeqUtils; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.userserver.modules.pay.controller.order.vo.PayRefundReqVO; -import cn.iocoder.yudao.userserver.modules.pay.controller.order.vo.PayRefundRespVO; -import cn.iocoder.yudao.userserver.modules.pay.convert.order.PayRefundConvert; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import lombok.extern.slf4j.Slf4j; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; - -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; - -@Api(tags = "退款订单") -@RestController -@RequestMapping("/pay/order") -@Validated -@Slf4j -public class PayRefundController { - - @Resource - private PayRefundCoreService payRefundCoreService; - - @PostMapping("/refund") - @ApiOperation("提交退款订单") - public CommonResult submitRefundOrder(@RequestBody PayRefundReqVO reqVO){ - PayRefundReqDTO req = PayRefundConvert.INSTANCE.convert(reqVO); - req.setUserIp(getClientIP()); - //TODO 测试暂时模拟生成商户退款订单 - if(StrUtil.isEmpty(reqVO.getMerchantRefundId())) { - req.setMerchantRefundId(PaySeqUtils.genMerchantRefundNo()); - } - return CommonResult.success( PayRefundConvert.INSTANCE.convert(payRefundCoreService.submitRefundOrder(req))); - } - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitReqVO.java deleted file mode 100644 index 407edb1..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitReqVO.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.pay.controller.order.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.experimental.Accessors; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.Map; - -@ApiModel("支付订单提交 Request VO") -@Data -@Accessors(chain = true) -public class PayOrderSubmitReqVO { - - @ApiModelProperty(value = "支付单编号", required = true, example = "1024") - @NotNull(message = "支付单编号不能为空") - private Long id; - - @ApiModelProperty(value = "支付渠道", required = true, example = "wx_pub") - @NotEmpty(message = "支付渠道不能为空") - private String channelCode; - - @ApiModelProperty(value = "支付渠道的额外参数", notes = "例如说,微信公众号需要传递 openid 参数") - private Map channelExtras; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitRespVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitRespVO.java deleted file mode 100644 index 907a979..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayOrderSubmitRespVO.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.pay.controller.order.vo; - -import io.swagger.annotations.ApiModel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@ApiModel("支付订单提交 Response VO") -@Data -@Accessors(chain = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayOrderSubmitRespVO { - - /** - * 调用支付渠道的响应结果 - */ - private Object invokeResponse; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java deleted file mode 100644 index 8287ba0..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundReqVO.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.pay.controller.order.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import javax.validation.constraints.NotEmpty; - -@ApiModel("退款订单 Req VO") -@Data -@NoArgsConstructor -@AllArgsConstructor -public class PayRefundReqVO { - - @ApiModelProperty(value = "支付订单编号自增", required = true, example = "10") - @NotEmpty(message = "支付订单编号自增") - private Long payOrderId; - - @ApiModelProperty(value = "退款金额", required = true, example = "1") - @NotEmpty(message = "退款金额") - private Long amount; - - @ApiModelProperty(value = "退款原因", required = true, example = "不喜欢") - @NotEmpty(message = "退款原因") - private String reason; - - @ApiModelProperty(value = "商户退款订单号", required = true, example = "MR202111180000000001") - //TODO 测试暂时模拟生成 - //@NotEmpty(message = "商户退款订单号") - private String merchantRefundId; - -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java deleted file mode 100644 index 29059ab..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/controller/order/vo/PayRefundRespVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.pay.controller.order.vo; - -import io.swagger.annotations.ApiModel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; - -@ApiModel("提交退款订单 Response VO") -@Data -@Accessors(chain = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class PayRefundRespVO { - - /** - * 支付退款单编号, 自增 - */ - private Long refundId; -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/order/PayRefundConvert.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/order/PayRefundConvert.java deleted file mode 100644 index 999a3ba..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/order/PayRefundConvert.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.userserver.modules.pay.convert.order; - -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundReqDTO; -import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayRefundRespDTO; -import cn.iocoder.yudao.userserver.modules.pay.controller.order.vo.PayRefundReqVO; -import cn.iocoder.yudao.userserver.modules.pay.controller.order.vo.PayRefundRespVO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * 支付退款 Convert - * - * @author jason - */ -@Mapper -public interface PayRefundConvert { - - PayRefundConvert INSTANCE = Mappers.getMapper(PayRefundConvert.class); - - PayRefundReqDTO convert(PayRefundReqVO reqVO); - - PayRefundRespVO convert(PayRefundRespDTO req); -} diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/package-info.java deleted file mode 100644 index 3f27f0b..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -/** - * 提供 POJO 类的实体转换 - * - * 目前使用 MapStruct 框架 - */ -package cn.iocoder.yudao.userserver.modules.pay.convert; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md deleted file mode 100644 index 8153487..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/package-info.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/package-info.java deleted file mode 100644 index 1aa11cd..0000000 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/pay/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * pay 包下,我们放支付业务,提供业务的支付能力。 - * 例如说:商户、应用、支付、退款等等 - * - * 缩写:pay - */ -package cn.iocoder.yudao.userserver.modules.pay; -- libgit2 0.21.4