From 4629533dda3424ce9d5b289b08ade6bd3cd80fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=AE=87=E5=A5=87?= Date: Mon, 7 Apr 2025 18:08:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=AE=A2=E5=8D=95=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=8F=91=E8=B5=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 + .../controller/xkt/StoreOrderController.java | 39 +++++- .../xkt/StoreProductColorController.java | 6 +- .../xkt/vo/order/StoreOrderAddReqVO.java | 10 +- .../xkt/vo/order/StoreOrderAddRespVO.java | 14 ++ .../core/controller/XktBaseController.java | 2 +- xkt/pom.xml | 5 + ...rAddResultDTO.java => StoreOrderInfo.java} | 2 +- .../ruoyi/xkt/dto/payment/AlipayReqDTO.java | 41 ++++++ .../java/com/ruoyi/xkt/enums/EPayChannel.java | 27 ++++ .../java/com/ruoyi/xkt/enums/EPayFrom.java | 29 +++++ .../com/ruoyi/xkt/manager/PaymentManager.java | 27 ++++ .../manager/impl/AliPaymentMangerImpl.java | 120 ++++++++++++++++++ .../ruoyi/xkt/service/IStoreOrderService.java | 12 +- .../impl/OperationRecordServiceImpl.java | 7 +- .../service/impl/StoreOrderServiceImpl.java | 57 ++++++++- 16 files changed, 379 insertions(+), 26 deletions(-) rename xkt/src/main/java/com/ruoyi/xkt/dto/order/{StoreOrderAddResultDTO.java => StoreOrderInfo.java} (91%) create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/payment/AlipayReqDTO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/enums/EPayChannel.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/enums/EPayFrom.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/manager/PaymentManager.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java diff --git a/pom.xml b/pom.xml index 76fbcb44a..5e077ab9f 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ 5.3.39 3.17.4 + 4.40.54.ALL @@ -252,6 +253,12 @@ ${aliyun-sdk-oss.version} + + com.alipay.sdk + alipay-sdk-java + ${alipay-sdk.version} + + co.elastic.clients diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java index a1eb588e2..a4006d724 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java @@ -5,12 +5,17 @@ import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.XktBaseController; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.web.controller.xkt.vo.order.StoreOrderAddReqVO; import com.ruoyi.web.controller.xkt.vo.order.StoreOrderAddRespVO; import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; -import com.ruoyi.xkt.dto.order.StoreOrderAddResultDTO; +import com.ruoyi.xkt.dto.order.StoreOrderInfo; +import com.ruoyi.xkt.enums.EPayChannel; +import com.ruoyi.xkt.enums.EPayFrom; +import com.ruoyi.xkt.manager.PaymentManager; import com.ruoyi.xkt.service.IStoreOrderService; +import io.jsonwebtoken.lang.Assert; import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; @@ -18,6 +23,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + /** * @author liangyq * @date 2025-04-03 14:18 @@ -29,6 +36,8 @@ public class StoreOrderController extends XktBaseController { @Autowired private IStoreOrderService storeOrderService; + @Autowired + private List paymentManagers; /** * 创建订单 @@ -39,8 +48,30 @@ public class StoreOrderController extends XktBaseController { public R create(@RequestBody StoreOrderAddReqVO vo) { StoreOrderAddDTO dto = BeanUtil.toBean(vo, StoreOrderAddDTO.class); dto.setOrderUserId(SecurityUtils.getUserId()); - StoreOrderAddResultDTO resultDTO = storeOrderService.createOrder(dto); - //TODO - return success(); + //初始化订单 + StoreOrderInfo orderInfo = storeOrderService.createOrder(dto); + //发起支付 + PaymentManager paymentManager = getPaymentManager(EPayChannel.of(vo.getPayChannel())); + String rtnStr = paymentManager.payForOrder(orderInfo.getOrder().getId(), EPayFrom.of(vo.getPayFrom())); + //返回信息 + StoreOrderAddRespVO respVO = new StoreOrderAddRespVO(orderInfo.getOrder().getId(), + orderInfo.getOrder().getOrderNo(), rtnStr); + return success(respVO); + } + + /** + * 根据支付渠道匹配支付类 + * + * @param payChannel + * @return + */ + private PaymentManager getPaymentManager(EPayChannel payChannel) { + Assert.notNull(payChannel); + for (PaymentManager paymentManager : paymentManagers) { + if (paymentManager.channel() == payChannel) { + return paymentManager; + } + } + throw new ServiceException("未知支付渠道"); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreProductColorController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreProductColorController.java index 1d26928ce..cef09fe78 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreProductColorController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreProductColorController.java @@ -14,6 +14,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + /** * 档口当前商品颜色Controller * @@ -34,8 +36,8 @@ public class StoreProductColorController extends XktBaseController { @PreAuthorize("@ss.hasPermi('system:color:query')") @ApiOperation(value = "模糊查询档口所有的商品颜色分类", httpMethod = "GET", response = R.class) @GetMapping(value = "/fuzzy") - public R fuzzyQueryColorList(@RequestParam(value = "prodArtNum", required = false) String prodArtNum, - @RequestParam("storeId") Long storeId) { + public R> fuzzyQueryColorList(@RequestParam(value = "prodArtNum", required = false) String prodArtNum, + @RequestParam("storeId") Long storeId) { return success(BeanUtil.copyToList(storeProdColorService.fuzzyQueryColorList(storeId, prodArtNum), StoreProdColorResVO.class)); } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderAddReqVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderAddReqVO.java index e56f96f7b..48c40e3db 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderAddReqVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderAddReqVO.java @@ -19,10 +19,6 @@ public class StoreOrderAddReqVO { */ @ApiModelProperty(value = "档口ID") private Long storeId; -// /** -// * 下单用户ID -// */ -// private Long orderUserId; /** * 订单备注 */ @@ -79,6 +75,12 @@ public class StoreOrderAddReqVO { @ApiModelProperty(value = "明细列表") private List detailList; + @ApiModelProperty(value = "支付渠道[1:支付宝]") + private Integer payChannel; + + @ApiModelProperty(value = "支付来源[1:电脑网站 2:手机网站]") + private Integer payFrom; + @ApiModel(value = "明细") @Data public static class Detail { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderAddRespVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderAddRespVO.java index a098a34ae..0bb3fe502 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderAddRespVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderAddRespVO.java @@ -1,7 +1,10 @@ package com.ruoyi.web.controller.xkt.vo.order; import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; /** * @author liangyq @@ -9,6 +12,17 @@ import lombok.Data; */ @ApiModel @Data +@AllArgsConstructor +@NoArgsConstructor public class StoreOrderAddRespVO { + @ApiModelProperty(value = "订单ID") + private Long storeOrderId; + + @ApiModelProperty(value = "订单号") + private String orderNo; + + @ApiModelProperty(value = "支付渠道返回值: 跳转页面数据/签名字符串/支付跳转链接/预支付交易会话标识(根据选择的支付渠道和支付来源确定)") + private String payRtnStr; + } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/XktBaseController.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/XktBaseController.java index b1a6d88a3..5753bc70b 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/XktBaseController.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/controller/XktBaseController.java @@ -109,7 +109,7 @@ public class XktBaseController { /** * 返回成功消息 */ - public R success(Object data) { + public R success(T data) { return R.ok(data); } diff --git a/xkt/pom.xml b/xkt/pom.xml index e6851a8b8..8707f0101 100644 --- a/xkt/pom.xml +++ b/xkt/pom.xml @@ -28,6 +28,11 @@ ruoyi-common + + com.alipay.sdk + alipay-sdk-java + + diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddResultDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfo.java similarity index 91% rename from xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddResultDTO.java rename to xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfo.java index 50b7d0309..0343b8319 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddResultDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfo.java @@ -15,7 +15,7 @@ import java.util.List; @Data @AllArgsConstructor @NoArgsConstructor -public class StoreOrderAddResultDTO { +public class StoreOrderInfo { private StoreOrder order; diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/payment/AlipayReqDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/payment/AlipayReqDTO.java new file mode 100644 index 000000000..961021b4b --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/payment/AlipayReqDTO.java @@ -0,0 +1,41 @@ +package com.ruoyi.xkt.dto.payment; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author liangyq + * @date 2025-04-07 16:15 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AlipayReqDTO { + /** + * 订单名称 + */ + @JsonProperty("subject") + private String subject; + /** + * 商户网站唯一订单号 + */ + @JsonProperty("out_trade_no") + private String outTradeNo; + /** + * 该笔订单允许的最晚付款时间 + */ + @JsonProperty("timeout_express") + private String timeoutExpress; + /** + * 付款金额 + */ + @JsonProperty("total_amount") + private String totalAmount; + /** + * 销售产品码,与支付宝签约的产品码名称 + */ + @JsonProperty("product_code") + private String productCode; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EPayChannel.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EPayChannel.java new file mode 100644 index 000000000..33f41abd5 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EPayChannel.java @@ -0,0 +1,27 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EPayChannel { + + ALI_PAY(1, "支付宝"); + + private final Integer value; + private final String label; + + public static EPayChannel of(Integer value) { + for (EPayChannel e : EPayChannel.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EPayFrom.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EPayFrom.java new file mode 100644 index 000000000..ac63e686f --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EPayFrom.java @@ -0,0 +1,29 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-07 10:01 + */ +@Getter +@AllArgsConstructor +public enum EPayFrom { + + WEB(1, "电脑网站"), + WAP(2, "手机网站"), + ; + + private final Integer value; + private final String label; + + public static EPayFrom of(Integer value) { + for (EPayFrom e : EPayFrom.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/PaymentManager.java b/xkt/src/main/java/com/ruoyi/xkt/manager/PaymentManager.java new file mode 100644 index 000000000..05d15e636 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/manager/PaymentManager.java @@ -0,0 +1,27 @@ +package com.ruoyi.xkt.manager; + +import com.ruoyi.xkt.enums.EPayChannel; +import com.ruoyi.xkt.enums.EPayFrom; + +/** + * @author liangyq + * @date 2025-04-06 19:36 + */ +public interface PaymentManager { + /** + * 支付渠道 + * + * @return + */ + EPayChannel channel(); + + /** + * 订单支付 + * + * @param storeOrderId + * @param payFrom + * @return 跳转页面数据/签名字符串/支付跳转链接/预支付交易会话标识(根据支付渠道&支付来源确定) + */ + String payForOrder(Long storeOrderId, EPayFrom payFrom); + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java new file mode 100644 index 000000000..2de6b57c9 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java @@ -0,0 +1,120 @@ +package com.ruoyi.xkt.manager.impl; + +import com.alibaba.fastjson2.JSON; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayClient; +import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.request.AlipayTradePagePayRequest; +import com.alipay.api.request.AlipayTradeWapPayRequest; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.xkt.dto.order.StoreOrderInfo; +import com.ruoyi.xkt.dto.payment.AlipayReqDTO; +import com.ruoyi.xkt.enums.EPayChannel; +import com.ruoyi.xkt.enums.EPayFrom; +import com.ruoyi.xkt.manager.PaymentManager; +import com.ruoyi.xkt.service.IStoreOrderService; +import io.jsonwebtoken.lang.Assert; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +/** + * @author liangyq + * @date 2025-04-06 19:36 + */ +@Slf4j +@Component +public class AliPaymentMangerImpl implements PaymentManager { + /** + * 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 + */ + @Value("${alipay.appId:9021000144616672}") + private String appId; + /** + * 商户私钥,您的PKCS8格式RSA2私钥 + */ + @Value("${alipay.privateKey:MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC3x52ARikELwpOPvPcpY9jj7aEWIPivfBwkf3YRyUKnM7L6mOTxD1v3b7QLcL1+l0QmvOPSGgt2O3Qbjtvq+5ih4T32TlAzHGe8VqGVqrEv7ANQicsXz600ze5LdxCDRgBZWhO/GroGJKfenHf7K+arN4KXWWmHyZHCYD5z85TEvZZoA9e9MTMskXeDS8+fwP6McuNf4fR07kVuzblks+wWm1PsWfxFM7qNwSYKXbmEoyDe7+M9vBr7cwuj2OB3PEtj/FZjKMxVnFyVm61KiFAGUf3oUqWmPASTPDkFboRCS/njv980hk3sPba/qMDfMEpjoMZrcLBVzoj747oEi/DAgMBAAECggEAcVoXlRSxG7l/278MXl1nUXtEkeCeh+2rLWN+dDV9bUxGaJOLE4sIccUNeg2foGPpnuJTs15vk0endtVmp3weLntz0gMTQxpWQjiPIyi1b2Djz2msC7w7SwCz7+2PWtYEpmfLrFwX/Eubs+2r6vdrYDWbRj1RAuNXkp0UBgDcO3P9AFeGln5gUWxni4biN6B9sGGdsSwcm1A9biBPRsH2zMSVVWkhLVq+S73smm2Sh7WTIVEyeAuWEDeMs5oI2jQjPHMlUKmWW6JZ3uD5xbRm3Nkvve/nvfJ4ZXx58ABTI9EWzcBlEuLYef4T+P9q4KHZQljpJ4UliIxUVIDSk3GNMQKBgQDevjYnLW2FBNDYQvPf6FkD2iNzKFe80cQYR0+/jiSBgkmtQhXZgyJ2ZqQ5t20MjgLpeY0WJL2twBlFcYGico6Vnv+JMiJDtIjTu1UozAqV2VPeJ34nX34nqJptGwehiPXJupAiulAWtvTqsiYWlFHsr3dMtj6z07M+gDV8PU7P/QKBgQDTOCGgdrS3XYD680eH9vGKbH1DpIOMr3JokLk6kv4yui9Jxk5DMCxcJWkEQRnCrw2UYM8PfX17FqXrwhccmR9hskSmmbLONYzk4SDB73fM2nPqBw+VLO6jbWctylUsGaYfVxDOLDWPQkktKUsHK8pQHLNQ4jwlP5SGQUoIM/OqvwKBgHfRrmPIxh9GBeovqeyKmke+Mk+iJgBGfsvooHeUyQJ5yZRP9lz5c7JpaHI7v4d/ZQWfA0wkG3y5115JvshaA2VtEF0HAPOWy/vJy/eUOyV8sObSK8SWU9CVm+yRG7vDZyRLHXnw62AsrvcJOf/vbVp60RwM9RHbEZLPePYKLLkpAoGADPMaDK56ceuHptsXfZyEPopcO7NwZUW0a/jDgnXUo+OKVqmTzsa7UYLxp1MeczMsT/aHe1mkQdGnpoalyBkTNXgqgVRXBBGAa9/plDpMTADwrl50dB7nGpnwg3wuMJ/58V3zJ9DKD9huiBhKA0yKANNhownbyiTVxE1oboxQ2h0CgYEAkV4hjGe4t6mu5rhqvuIZkDskjuSOwO0dZsGXBZ/sOZusKNmskxeNZht4BajnATN4EaPg265k8ytWnOEQH041J8Wac1M+jAQQp6D1nkQWZZlrclTu7xvM+p6ypVtqNFTseIQtEhtyPw+fcsYrXM4u8LHpGlAzlwQ30lFg+K/Q++Y=}") + private String privateKey; + /** + * 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 + */ + @Value("${alipay.publicKey:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkiTTeQLIkyVHnYiNmRKEtsdlwKftUySN1SLkrhn6CgmHl5ovjPeYteweZEZmsf2kt6wRnaLkODVP7xUQiRVC2cu6StdJyvDzyiYI00u72PvSOvaWHcpzgKqTFpGiQseJQlHnI8U3ob4PxfJylBy8RDQHG9fZwNY1WOCsnSb3m2ufV1EQIjndzTq13yQE6jCz639rO8atlAG3PtJW/QRiGUzyGaOuKsS4HRzPbbpmVtsXoN76+x+WLWkeqlTBEu35X4Hdbkf1C36wp3b68sI5fVyLksF6elRv/It4aUzjXSXbO/Dx+zvMIN01FgwaFV6nLh++k3qlmo87p4I+hvsGiQIDAQAB}") + private String alipayPublicKey; + /** + * 服务器异步通知页面路径 + */ + @Value("${alipay.notifyUrl:}") + private String notifyUrl; + /** + * 页面跳转同步通知页面路径 + */ + @Value("${alipay.returnUrl:}") + private String returnUrl; + /** + * 签名方式 + */ + @Value("${alipay.signType:RSA2}") + private String signType; + /** + * 字符编码格式 + */ + @Value("${alipay.charset:UTF-8}") + private String charset; + /** + * 支付宝网关 + */ + @Value("${alipay.gatewayUrl:https://openapi-sandbox.dl.alipaydev.com/gateway.do}") + private String gatewayUrl; + + @Autowired + private IStoreOrderService storeOrderService; + + @Override + public EPayChannel channel() { + return EPayChannel.ALI_PAY; + } + + @Override + public String payForOrder(Long storeOrderId, EPayFrom payFrom) { + Assert.notNull(storeOrderId); + Assert.notNull(payFrom); + //订单状态更新为支付中 + StoreOrderInfo order = storeOrderService.preparePayOrder(storeOrderId); + AlipayReqDTO reqDTO = new AlipayReqDTO(); + reqDTO.setOutTradeNo(order.getOrder().getOrderNo()); + reqDTO.setTotalAmount(order.getOrder().getTotalAmount().toPlainString()); + reqDTO.setSubject("代发订单" + order.getOrder().getOrderNo()); + reqDTO.setProductCode("FAST_INSTANT_TRADE_PAY"); //这个是固定的 + String reqStr = JSON.toJSONString(reqDTO); + AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, "json", charset, + alipayPublicKey, signType); + switch (payFrom) { + case WEB: + AlipayTradePagePayRequest webReq = new AlipayTradePagePayRequest(); + webReq.setReturnUrl(returnUrl); + webReq.setNotifyUrl(notifyUrl); + webReq.setBizContent(reqStr); + try { + return alipayClient.pageExecute(webReq).getBody(); + } catch (AlipayApiException e) { + log.error("支付发起异常", e); + throw new ServiceException("支付发起失败"); + } + case WAP: + AlipayTradeWapPayRequest wapReq = new AlipayTradeWapPayRequest(); + wapReq.setReturnUrl(returnUrl); + wapReq.setNotifyUrl(notifyUrl); + wapReq.setBizContent(reqStr); + try { + return alipayClient.pageExecute(wapReq).getBody(); + } catch (AlipayApiException e) { + log.error("支付发起异常", e); + throw new ServiceException("支付发起失败"); + } + default: + throw new ServiceException("未知的支付来源"); + } + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java index 87c27d418..18bc851e6 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java @@ -1,8 +1,7 @@ package com.ruoyi.xkt.service; import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; -import com.ruoyi.xkt.dto.order.StoreOrderAddResultDTO; -import com.ruoyi.xkt.dto.order.StoreOrderInfoDTO; +import com.ruoyi.xkt.dto.order.StoreOrderInfo; /** * @author liangyq @@ -15,5 +14,12 @@ public interface IStoreOrderService { * @param storeOrderAddDTO * @return */ - StoreOrderAddResultDTO createOrder(StoreOrderAddDTO storeOrderAddDTO); + StoreOrderInfo createOrder(StoreOrderAddDTO storeOrderAddDTO); + + /** + * 准备支付订单 + * + * @param storeOrderId + */ + StoreOrderInfo preparePayOrder(Long storeOrderId); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/OperationRecordServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/OperationRecordServiceImpl.java index df6855f31..5d1af4f69 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/OperationRecordServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/OperationRecordServiceImpl.java @@ -8,9 +8,9 @@ import com.ruoyi.xkt.mapper.StoreOrderOperationRecordMapper; import com.ruoyi.xkt.service.IOperationRecordService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.stream.Collectors; /** * @author liangyq @@ -22,14 +22,13 @@ public class OperationRecordServiceImpl implements IOperationRecordService { @Autowired private StoreOrderOperationRecordMapper storeOrderOperationRecordMapper; + @Transactional @Override public void addOrderOperationRecords(List recordList) { if (CollUtil.isEmpty(recordList)) { return; } - List list = recordList.stream() - .map(dto -> BeanUtil.toBean(dto, StoreOrderOperationRecord.class)) - .collect(Collectors.toList()); + List list = BeanUtil.copyToList(recordList, StoreOrderOperationRecord.class); storeOrderOperationRecordMapper.batchInsert(list); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java index c304a156c..dd8d88ce8 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java @@ -6,13 +6,14 @@ import cn.hutool.core.lang.Assert; import cn.hutool.core.util.NumberUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.domain.SimpleEntity; import com.ruoyi.common.core.domain.XktBaseEntity; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.bean.BeanValidators; import com.ruoyi.xkt.domain.*; import com.ruoyi.xkt.dto.express.ExpressContactDTO; import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; -import com.ruoyi.xkt.dto.order.StoreOrderAddResultDTO; +import com.ruoyi.xkt.dto.order.StoreOrderInfo; import com.ruoyi.xkt.dto.order.StoreOrderOperationRecordAddDTO; import com.ruoyi.xkt.enums.*; import com.ruoyi.xkt.mapper.*; @@ -53,7 +54,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService { @Transactional @Override - public StoreOrderAddResultDTO createOrder(StoreOrderAddDTO storeOrderAddDTO) { + public StoreOrderInfo createOrder(StoreOrderAddDTO storeOrderAddDTO) { Long orderUserId = storeOrderAddDTO.getOrderUserId(); Long storeId = storeOrderAddDTO.getStoreId(); Long expressId = storeOrderAddDTO.getExpressId(); @@ -159,7 +160,48 @@ public class StoreOrderServiceImpl implements IStoreOrderService { }); //操作记录 addOperationRecords(orderId, orderDetailIdList, orderUserId, new Date(), EOrderAction.ADD_ORDER); - return new StoreOrderAddResultDTO(order, orderDetailList); + return new StoreOrderInfo(order, orderDetailList); + } + + @Transactional + @Override + public StoreOrderInfo preparePayOrder(Long storeOrderId) { + Assert.notNull(storeOrderId); + StoreOrder order = storeOrderMapper.selectById(storeOrderId); + Assert.isTrue(EOrderType.SALES_ORDER.getValue().equals(order.getOrderType()), + "非销售订单无法发起支付"); + Assert.isTrue(BeanValidators.exists(order), "订单不存在"); + List orderDetails = storeOrderDetailMapper.selectList( + Wrappers.lambdaQuery(StoreOrderDetail.class) + .eq(StoreOrderDetail::getStoreOrderId, storeOrderId) + .eq(SimpleEntity::getDelFlag, Constants.UNDELETED)); + checkPreparePayStatus(order.getPayStatus()); + StoreOrder updateOrder = new StoreOrder(); + updateOrder.setId(storeOrderId); + updateOrder.setPayStatus(EPayStatus.PAYING.getValue()); + updateOrder.setVersion(order.getVersion()); + int orderSuccess = storeOrderMapper.updateById(updateOrder); + if (orderSuccess == 0) { + throw new ServiceException("系统繁忙请稍后再试"); + } + for (StoreOrderDetail orderDetail : orderDetails) { + checkPreparePayStatus(orderDetail.getPayStatus()); + StoreOrderDetail orderDetailUpdate = new StoreOrderDetail(); + orderDetailUpdate.setId(orderDetail.getId()); + orderDetailUpdate.setPayStatus(EPayStatus.PAYING.getValue()); + orderDetailUpdate.setVersion(orderDetail.getVersion()); + int orderDetailSuccess = storeOrderDetailMapper.updateById(orderDetailUpdate); + if (orderDetailSuccess == 0) { + throw new ServiceException("系统繁忙请稍后再试"); + } + } + return new StoreOrderInfo(order, orderDetails); + } + + private void checkPreparePayStatus(Integer payStatus) { + if (!EPayStatus.INIT.getValue().equals(payStatus) && !EPayStatus.PAYING.getValue().equals(payStatus)) { + throw new ServiceException("订单状态异常无法发起支付"); + } } /** @@ -212,11 +254,12 @@ public class StoreOrderServiceImpl implements IStoreOrderService { BigDecimal price = productColorPrice.getPrice(); if (ProductSizeStatus.UN_STANDARD.getValue().equals(storeProductColorSize.getStandard())) { //非标准尺码 - StoreProduct product = storeProductMapper.selectById(storeProductColorSize.getStoreProdId()); - BigDecimal addPrice = BigDecimal.valueOf(NumberUtil.nullToZero(product.getOverPrice())); - price = NumberUtil.add(price, addPrice); +// StoreProduct product = storeProductMapper.selectById(storeProductColorSize.getStoreProdId()); +// BigDecimal addPrice = BigDecimal.valueOf(NumberUtil.nullToZero(product.getOverPrice())); +// price = NumberUtil.add(price, addPrice); + //非标准尺码不存在线上下单 + throw new ServiceException("商品尺码异常"); } - //TODO 客户优惠 return price; }