From 66abe4a84b631f70fae8f8674e9eee6ebe77a831 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 27 Nov 2022 19:42:49 +0800 Subject: [PATCH] =?UTF-8?q?trade=EF=BC=9A=E5=AE=8C=E6=88=90=E4=BA=A4?= =?UTF-8?q?=E6=98=93=E8=AE=A2=E5=8D=95=E7=9A=84=E5=8F=91=E8=B4=A7=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/dto/PayOrderUnifiedReqDTO.java | 2 +- .../client/dto/PayRefundUnifiedReqDTO.java | 2 +- .../core/client/impl/AbstractPayClient.java | 2 +- .../PayClientFactoryImplIntegrationTest.java | 2 +- .../alipay/AlipayQrPayClientTest.java | 2 +- .../trade/enums/ErrorCodeConstants.java | 7 +- .../order/TradeOrderDeliveryStatusEnum.java | 28 +++ .../enums/order/TradeOrderStatusEnum.java | 21 ++ .../admin/order/TradeOrderController.java | 40 ++++ .../order/vo/TradeOrderDeliveryReqVO.java | 26 ++ .../vo/AppTradeAfterSaleDeliveryReqVO.java | 3 +- .../dal/dataobject/order/TradeOrderDO.java | 15 +- .../service/order/TradeOrderService.java | 27 ++- .../service/order/TradeOrderServiceImpl.java | 226 +++++++++++------- .../service/order/TradeOrderServiceTest.java | 44 +++- .../src/test/resources/sql/create_tables.sql | 5 +- .../dal/dataobject/refund/PayRefundDO.java | 4 +- .../service/order/dto/PayRefundReqDTO.java | 2 +- 18 files changed, 332 insertions(+), 126 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java index ea3628931..5314453be 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java @@ -62,7 +62,7 @@ public class PayOrderUnifiedReqDTO { */ @NotNull(message = "支付金额不能为空") @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") - private Long amount; + private Integer amount; /** * 支付过期时间 diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java index 79e11eaff..50c933aaa 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayRefundUnifiedReqDTO.java @@ -63,7 +63,7 @@ public class PayRefundUnifiedReqDTO { */ @NotNull(message = "退款金额不能为空") @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") - private Long amount; + private Integer amount; /** * 退款结果 notify 回调地址, 支付宝退款不需要回调地址, 微信需要 diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java index 3253709c8..2ff978dba 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/AbstractPayClient.java @@ -69,7 +69,7 @@ public abstract class AbstractPayClient implemen this.init(); } - protected Double calculateAmount(Long amount) { + protected Double calculateAmount(Integer amount) { return amount / 100.0; } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/PayClientFactoryImplIntegrationTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/PayClientFactoryImplIntegrationTest.java index 4ba9e5088..975483954 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/PayClientFactoryImplIntegrationTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/PayClientFactoryImplIntegrationTest.java @@ -122,7 +122,7 @@ public class PayClientFactoryImplIntegrationTest { private static PayOrderUnifiedReqDTO buildPayOrderUnifiedReqDTO() { PayOrderUnifiedReqDTO reqDTO = new PayOrderUnifiedReqDTO(); - reqDTO.setAmount(123L); + reqDTO.setAmount(123); reqDTO.setSubject("IPhone 13"); reqDTO.setBody("biubiubiu"); reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis())); diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/alipay/AlipayQrPayClientTest.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/alipay/AlipayQrPayClientTest.java index 9ded6f026..f3950792d 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/alipay/AlipayQrPayClientTest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn.iocoder.yudao.framework.pay.core.client.impl/alipay/AlipayQrPayClientTest.java @@ -73,7 +73,7 @@ public class AlipayQrPayClientTest extends BaseMockitoUnitTest { Long shopOrderId = System.currentTimeMillis(); PayOrderUnifiedReqDTO reqDTO=new PayOrderUnifiedReqDTO(); reqDTO.setMerchantOrderId(String.valueOf(System.currentTimeMillis())); - reqDTO.setAmount(1L); + reqDTO.setAmount(1); reqDTO.setBody("内容:" + shopOrderId); reqDTO.setSubject("标题:"+shopOrderId); String notify="http://niubi.natapp1.cc/api/pay/order/notify"; diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index ebe2cea51..52f709111 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -23,9 +23,10 @@ public interface ErrorCodeConstants { ErrorCode ORDER_NOT_FOUND = new ErrorCode(1011000011, "交易订单不存在"); ErrorCode ORDER_ITEM_UPDATE_AFTER_SALE_STATUS_FAIL = new ErrorCode(1011000012, "交易订单项更新售后状态失败,请重试"); ErrorCode ORDER_UPDATE_PAID_STATUS_NOT_UNPAID = new ErrorCode(1011000013, "交易订单更新支付状态失败,订单不是【未支付】状态"); - ErrorCode ORDER_UPDATE_PAID_PAY_ORDER_ID_ERROR = new ErrorCode(1011000014, "交易订单更新支付状态失败,支付单编号不匹配"); - ErrorCode ORDER_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1011000015, "交易订单更新支付状态失败,支付单状态不是【支付成功】状态"); - ErrorCode ORDER_UPDATE_PAID_PAY_PRICE_NOT_MATCH = new ErrorCode(1011000016, "交易订单更新支付状态失败,支付单金额不匹配"); + ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR = new ErrorCode(1011000014, "交易订单更新支付状态失败,支付单编号不匹配"); + ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS = new ErrorCode(1011000015, "交易订单更新支付状态失败,支付单状态不是【支付成功】状态"); + ErrorCode ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH = new ErrorCode(1011000016, "交易订单更新支付状态失败,支付单金额不匹配"); + ErrorCode ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED = new ErrorCode(1011000017, "交易订单发货失败,订单不是【待发货】状态"); // ========== After Sale 模块 1-011-000-000 ========== ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java new file mode 100644 index 000000000..27b061e37 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderDeliveryStatusEnum.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.trade.enums.order; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 交易订单 - 发货状态 + * + * @author 芋道源码 + */ +@RequiredArgsConstructor +@Getter +public enum TradeOrderDeliveryStatusEnum { + + UNDELIVERED(0, "未发货"), + DELIVERED(1, "已发货"), + RECEIVED(2, "已收货"); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java index a234bcca5..f95fc18a3 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java @@ -52,9 +52,30 @@ public enum TradeOrderStatusEnum implements IntArrayValuable { * @return 是否 */ public static boolean isUnpaid(Integer status) { + return ObjectUtil.equal(UNPAID.getStatus(), status); + } + + /** + * 判断指定状态,是否正处于【已支付】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean isPaid(Integer status) { return ObjectUtil.equal(PAID.getStatus(), status); } + /** + * 判断指定状态,是否正处于【待发货】状态 + * + * @param status 指定状态 + * @return 是否 + */ + public static boolean isUndelivered(Integer status) { + return ObjectUtil.equal(UNDELIVERED.getStatus(), status); + } + + /** * 判断指定状态,是否正处于【已取消】状态 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java new file mode 100644 index 000000000..47b6dace8 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderService; +import io.swagger.annotations.Api; +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.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.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Api(tags = "管理后台 - 交易订单") +@RestController +@RequestMapping("/trade/order") +@Validated +@Slf4j +public class TradeOrderController { + + @Resource + private TradeOrderService tradeOrderService; + + @PostMapping("/delivery") + @ApiOperation("发货订单") + @PreAuthorize("@ss.hasPermission('trade:order:delivery')") + public CommonResult deliveryOrder(@RequestBody TradeOrderDeliveryReqVO deliveryReqVO) { + tradeOrderService.deliveryOrder(getLoginUserId(), deliveryReqVO); + return success(true); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java new file mode 100644 index 000000000..e75fcacf2 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDeliveryReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@ApiModel("管理后台 - 订单发货 Request VO") +@Data +public class TradeOrderDeliveryReqVO { + + @ApiModelProperty(name = "订单编号", required = true, example = "1024") + @NotNull(message = "订单编号不能为空") + private Long id; + + @ApiModelProperty(name = "发货物流公司编号", required = true, example = "1") + @NotNull(message = "发货物流公司编号不能为空") + private Long logisticsId; + + @ApiModelProperty(name = "发货物流单号", required = true, example = "SF123456789") + @NotEmpty(message = "发货物流单号不能为空") + private String logisticsNo; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java index 0727361d7..c59d00034 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/aftersale/vo/AppTradeAfterSaleDeliveryReqVO.java @@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.time.LocalDateTime; @@ -24,7 +25,7 @@ public class AppTradeAfterSaleDeliveryReqVO { private String logisticsNo; @ApiModelProperty(name = "退货时间", required = true) - @NotNull(message = "退货时间不能为空") + @NotEmpty(message = "退货时间不能为空") private LocalDateTime deliveryTime; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index 4d0d14f45..421bbe355 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO.OrderItem; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderCancelTypeEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderDeliveryStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -178,20 +179,24 @@ public class TradeOrderDO extends BaseDO { */ private Long deliveryTemplateId; /** - * 物流公司单号 + * 发货物流公司编号 */ - private String expressNo; + private Long logisticsId; + /** + * 发货物流单号 + */ + private String logisticsNo; /** * 发货状态 * - * true - 已发货 - * false - 未发货 + * 枚举 {@link TradeOrderDeliveryStatusEnum} */ - private Boolean deliveryStatus; + private Integer deliveryStatus; /** * 发货时间 */ private LocalDateTime deliveryTime; + /** * 收货时间 */ diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java index 5c59e1c88..389b41d3d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderService.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.trade.service.order; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -15,7 +16,7 @@ public interface TradeOrderService { // =================== Order =================== /** - * 创建交易订单 + * 【会员】创建交易订单 * * @param userId 登录用户 * @param userIp 用户 IP 地址 @@ -24,6 +25,22 @@ public interface TradeOrderService { */ Long createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO); + /** + * 更新交易订单已支付 + * + * @param id 交易订单编号 + * @param payOrderId 支付订单编号 + */ + void updateOrderPaid(Long id, Long payOrderId); + + /** + * 【管理员】发货交易订单 + * + * @param userId 管理员编号 + * @param deliveryReqVO 发货请求 + */ + void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO); + /** * 获得指定用户,指定的交易订单 * @@ -33,14 +50,6 @@ public interface TradeOrderService { */ TradeOrderDO getOrder(Long userId, Long orderId); - /** - * 更新交易订单已支付 - * - * @param id 交易订单编号 - * @param payOrderId 支付订单编号 - */ - void updateOrderPaid(Long id, Long payOrderId); - // =================== Order Item =================== /** diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index 3c5b59509..44f0c3ea7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -24,6 +24,7 @@ import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO; import cn.iocoder.yudao.module.promotion.api.price.PriceApi; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO.Item; import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; @@ -107,94 +108,6 @@ public class TradeOrderServiceImpl implements TradeOrderService { return tradeOrderDO.getId(); } - @Override - public TradeOrderDO getOrder(Long userId, Long orderId) { - TradeOrderDO order = tradeOrderMapper.selectById(orderId); - if (order != null - && ObjectUtil.notEqual(order.getUserId(), userId)) { - return null; - } - return order; - } - - @Override - public void updateOrderPaid(Long id, Long payOrderId) { - // 校验并获得交易订单 - KeyValue orderResult = validateOrderPaid(id, payOrderId); - TradeOrderDO order = orderResult.getKey(); - PayOrderRespDTO payOrder = orderResult.getValue(); - - // 更新 TradeOrderDO 状态为已支付,等待发货 - int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), - new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayed(true) - .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode())); - if (updateCount == 0) { - throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); - } - - // TODO 芋艿:发送订单变化的消息 - - // TODO 芋艿:发送站内信 - - // TODO 芋艿:OrderLog - } - - /** - * 校验交易订单满足被支付的条件 - * - * 1. 交易订单未支付 - * 2. 支付单已支付 - * - * @param id 交易订单编号 - * @param payOrderId 支付订单编号 - * @return 交易订单 - */ - private KeyValue validateOrderPaid(Long id, Long payOrderId) { - // 校验订单是否存在 - TradeOrderDO order = tradeOrderMapper.selectById(id); - if (order == null) { - throw exception(ORDER_NOT_FOUND); - } - // 校验订单未支付 - if (TradeOrderStatusEnum.isUnpaid(order.getStatus())) { // 状态 - log.error("[validateOrderPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]", - id, JsonUtils.toJsonString(order)); - throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); - } - // 校验支付订单匹配 - if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号 - log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(order)); - throw exception(ORDER_UPDATE_PAID_PAY_ORDER_ID_ERROR); - } - - // 校验支付单是否存在 - PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); - if (payOrder == null) { - log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); - throw exception(PAY_ORDER_NOT_FOUND); - } - // 校验支付单已支付 - if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { - log.error("[validateOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS); - } - // 校验支付金额一致 - if (ObjectUtil.notEqual(payOrder.getAmount(), order.getPayPrice())) { - log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_PAY_PRICE_NOT_MATCH); - } - // 校验支付订单匹配(二次) - if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) { - log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", - id, payOrderId, JsonUtils.toJsonString(payOrder)); - throw exception(ORDER_UPDATE_PAID_PAY_ORDER_ID_ERROR); - } - return new KeyValue<>(order, payOrder); - } - /** * 校验商品 SKU 是否可出售 * @@ -269,7 +182,7 @@ public class TradeOrderServiceImpl implements TradeOrderService { tradeOrderDO.setProductCount(getSumValue(order.getItems(), PriceCalculateRespDTO.OrderItem::getCount, Integer::sum)); tradeOrderDO.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? tradeOrderDO.setAdjustPrice(0).setPayed(false); // 支付信息 - tradeOrderDO.setDeliveryStatus(false); // 物流信息 + tradeOrderDO.setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); // 物流信息 tradeOrderDO.setAfterSaleStatus(TradeOrderAfterSaleStatusEnum.NONE.getStatus()).setRefundPrice(0); // 退款信息 tradeOrderMapper.insert(tradeOrderDO); return tradeOrderDO; @@ -324,7 +237,142 @@ public class TradeOrderServiceImpl implements TradeOrderService { tradeOrderMapper.updateById(new TradeOrderDO().setId(tradeOrderDO.getId()).setPayOrderId(payOrderId)); } + @Override + public void updateOrderPaid(Long id, Long payOrderId) { + // 校验并获得交易订单(可支付) + KeyValue orderResult = validateOrderPayable(id, payOrderId); + TradeOrderDO order = orderResult.getKey(); + PayOrderRespDTO payOrder = orderResult.getValue(); + // 更新 TradeOrderDO 状态为已支付,等待发货 + int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), + new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayed(true) + .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode())); + if (updateCount == 0) { + throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); + } + + // TODO 芋艿:发送订单变化的消息 + + // TODO 芋艿:发送站内信 + + // TODO 芋艿:OrderLog + } + + /** + * 校验交易订单满足被支付的条件 + * + * 1. 交易订单未支付 + * 2. 支付单已支付 + * + * @param id 交易订单编号 + * @param payOrderId 支付订单编号 + * @return 交易订单 + */ + private KeyValue validateOrderPayable(Long id, Long payOrderId) { + // 校验订单是否存在 + TradeOrderDO order = tradeOrderMapper.selectById(id); + if (order == null) { + throw exception(ORDER_NOT_FOUND); + } + // 校验订单未支付 + if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayed()) { + log.error("[validateOrderPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]", + id, JsonUtils.toJsonString(order)); + throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); + } + // 校验支付订单匹配 + if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号 + log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]", + id, payOrderId, JsonUtils.toJsonString(order)); + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); + } + + // 校验支付单是否存在 + PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); + if (payOrder == null) { + log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); + throw exception(PAY_ORDER_NOT_FOUND); + } + // 校验支付单已支付 + if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { + log.error("[validateOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", + id, payOrderId, JsonUtils.toJsonString(payOrder)); + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); + } + // 校验支付金额一致 + if (ObjectUtil.notEqual(payOrder.getAmount(), order.getPayPrice())) { + log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", + id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder)); + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); + } + // 校验支付订单匹配(二次) + if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) { + log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", + id, payOrderId, JsonUtils.toJsonString(payOrder)); + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); + } + return new KeyValue<>(order, payOrder); + } + + @Override + public void deliveryOrder(Long userId, TradeOrderDeliveryReqVO deliveryReqVO) { + // 校验并获得交易订单(可发货) + TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); + + // TODO 芋艿:logisticsId 校验存在 + + // 更新 TradeOrderDO 状态为已发货,等待收货 + int updateCount = tradeOrderMapper.updateByIdAndStatus(order.getId(), order.getStatus(), + new TradeOrderDO().setStatus(TradeOrderStatusEnum.DELIVERED.getStatus()) + .setLogisticsId(deliveryReqVO.getLogisticsId()).setLogisticsNo(deliveryReqVO.getLogisticsNo()) + .setDeliveryStatus(TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()).setDeliveryTime(LocalDateTime.now())); + if (updateCount == 0) { + throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); + } + + // TODO 芋艿:发送订单变化的消息 + + // TODO 芋艿:发送站内信 + + // TODO 芋艿:OrderLog + + // TODO 设计:like:是否要单独一个 delivery 发货单表??? + // TODO 设计:niu:要不要支持一个订单下,多个 order item 单独发货,类似有赞 + // TODO 设计:lili:是不是发货后,才支持售后? + } + + /** + * 校验交易订单满足被发货的条件 + * + * 1. 交易订单未发货 + * + * @param id 交易订单编号 + * @return 交易订单 + */ + private TradeOrderDO validateOrderDeliverable(Long id) { + // 校验订单是否存在 + TradeOrderDO order = tradeOrderMapper.selectById(id); + if (order == null) { + throw exception(ORDER_NOT_FOUND); + } + // 校验订单是否是待发货状态 + if (!TradeOrderStatusEnum.isUndelivered(order.getStatus()) + || ObjectUtil.notEqual(order.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus())) { + throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED); + } + return order; + } + + @Override + public TradeOrderDO getOrder(Long userId, Long orderId) { + TradeOrderDO order = tradeOrderMapper.selectById(orderId); + if (order != null + && ObjectUtil.notEqual(order.getUserId(), userId)) { + return null; + } + return order; + } // =================== Order Item =================== diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java index 77d34e494..302d27d40 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java @@ -16,15 +16,13 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; import cn.iocoder.yudao.module.promotion.api.price.PriceApi; import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; +import cn.iocoder.yudao.module.trade.enums.order.*; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderConfig; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import org.junit.jupiter.api.BeforeEach; @@ -38,6 +36,8 @@ import java.util.Arrays; import java.util.List; import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static java.util.Collections.singletonList; import static org.junit.jupiter.api.Assertions.*; @@ -173,8 +173,8 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { assertEquals(tradeOrderDO.getPayOrderId(), 1000L); assertNull(tradeOrderDO.getPayChannelCode()); assertNull(tradeOrderDO.getDeliveryTemplateId()); - assertNull(tradeOrderDO.getExpressNo()); - assertFalse(tradeOrderDO.getDeliveryStatus()); + assertNull(tradeOrderDO.getLogisticsId()); + assertEquals(tradeOrderDO.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); assertNull(tradeOrderDO.getDeliveryTime()); assertNull(tradeOrderDO.getReceiveTime()); assertEquals(tradeOrderDO.getReceiverName(), "芋艿"); @@ -246,11 +246,11 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { } @Test - public void updateOrderPaid() { + public void testUpdateOrderPaid() { // mock 数据(TradeOrder) TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { o.setId(1L).setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); - o.setPayOrderId(10L).setPayPrice(100).setPayTime(null); + o.setPayOrderId(10L).setPayed(false).setPayPrice(100).setPayTime(null); }); tradeOrderMapper.insert(order); // 准备参数 @@ -260,13 +260,39 @@ public class TradeOrderServiceTest extends BaseDbUnitTest { when(payOrderApi.getOrder(eq(10L))).thenReturn(randomPojo(PayOrderRespDTO.class, o -> o.setStatus(PayOrderStatusEnum.SUCCESS.getStatus()).setChannelCode("wx_pub") .setMerchantOrderId("1")).setAmount(100)); + // 调用 tradeOrderService.updateOrderPaid(id, payOrderId); // 断言 TradeOrderDO dbOrder = tradeOrderMapper.selectById(id); - assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.PAID.getStatus()); + assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus()); assertTrue(dbOrder.getPayed()); assertNotNull(dbOrder.getPayTime()); assertEquals(dbOrder.getPayChannelCode(), "wx_pub"); } + + @Test + public void testDeliveryOrder() { + // mock 数据(TradeOrder) + TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { + o.setId(1L).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()); + o.setLogisticsId(null).setLogisticsNo(null).setDeliveryTime(null) + .setDeliveryStatus(TradeOrderDeliveryStatusEnum.UNDELIVERED.getStatus()); + }); + tradeOrderMapper.insert(order); + // 准备参数 + TradeOrderDeliveryReqVO deliveryReqVO = new TradeOrderDeliveryReqVO().setId(1L) + .setLogisticsId(10L).setLogisticsNo("100"); + // mock 方法(支付单) + + // 调用 + tradeOrderService.deliveryOrder(randomLongId(), deliveryReqVO); + // 断言 + TradeOrderDO dbOrder = tradeOrderMapper.selectById(1L); + assertEquals(dbOrder.getStatus(), TradeOrderStatusEnum.DELIVERED.getStatus()); + assertEquals(dbOrder.getDeliveryStatus(), TradeOrderDeliveryStatusEnum.DELIVERED.getStatus()); + assertPojoEquals(dbOrder, deliveryReqVO); + assertNotNull(dbOrder.getDeliveryTime()); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql index d107d04cd..f3957898a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql +++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql @@ -20,10 +20,11 @@ CREATE TABLE IF NOT EXISTS "trade_order" ( "delivery_price" int NOT NULL, "adjust_price" int NOT NULL, "pay_price" int NOT NULL, - "pay_order_id" int, + "pay_order_id" bigint, "pay_channel_code" varchar, "delivery_template_id" bigint, - "express_no" varchar, + "logistics_id" bigint, + "logistics_no" varchar, "delivery_status" bit NOT NULL, "delivery_time" datetime, "receive_time" datetime, diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java index 06788440d..448cce30d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/refund/PayRefundDO.java @@ -132,11 +132,11 @@ public class PayRefundDO extends BaseDO { /** * 支付金额,单位:分 */ - private Long payAmount; + private Integer payAmount; /** * 退款金额,单位:分 */ - private Long refundAmount; + private Integer refundAmount; /** * 退款原因 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java index 0eb24dbe2..31d19b91a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/dto/PayRefundReqDTO.java @@ -31,7 +31,7 @@ public class PayRefundReqDTO { */ @NotNull(message = "退款金额不能为空") @DecimalMin(value = "0", inclusive = false, message = "退款金额必须大于零") - private Long amount; + private Integer amount; /** * 退款原因