尚品汇-订单拆单、付出宝关闭交易、关闭过期订单整合(五十) ...

打印 上一主题 下一主题

主题 844|帖子 844|积分 2532

目录:
(1)拆单接口
(2)取消订单业务增补关闭付出记载
(3)付出宝关闭交易
(4)查询付出交易记载
 (5)PaymentFeignClient 长途接口
(6)整合关闭过期订单 
(1)拆单接口



堆栈表:不是同一个堆栈 




 


 

 

 在service_order模块
订单实现拆单接口OrderService
  1. List<OrderInfo> orderSplit(Long orderId, String wareSkuMap);
复制代码


 拆单接口实现类OrderServiceImpl
  1. @Override
  2. @Transactional
  3. public List<OrderInfo> orderSplit(Long orderId, String wareSkuMap) {
  4.     ArrayList<OrderInfo> orderInfoArrayList = new ArrayList<>();
  5.     /*
  6.     1.  先获取到原始订单 107
  7.     2.  将wareSkuMap 转换为我们能操作的对象 [{"wareId":"1","skuIds":["2","10"]},{"wareId":"2","skuIds":["3"]}]
  8.         方案一:class Param{
  9.                     private String wareId;
  10.                     private List<String> skuIds;
  11.                 }
  12.         方案二:看做一个Map mpa.put("wareId",value); map.put("skuIds",value)
  13.     3.  创建一个新的子订单 108 109 。。。
  14.     4.  给子订单赋值
  15.     5.  保存子订单到数据库
  16.     6.  修改原始订单的状态
  17.     7.  测试
  18.      */
  19.    //获取父订单
  20.     OrderInfo orderInfoOrigin = getOrderInfoById(orderId);
  21.     List<Map> maps = JSON.parseArray(wareSkuMap, Map.class);
  22.     if (maps != null) {
  23.         for (Map map : maps) {
  24.             String wareId = (String) map.get("wareId");
  25.             List<String> skuIds = (List<String>) map.get("skuIds");
  26.             OrderInfo subOrderInfo = new OrderInfo();
  27.             // 属性拷贝
  28.             BeanUtils.copyProperties(orderInfoOrigin, subOrderInfo);
  29.             // 防止主键冲突
  30.             subOrderInfo.setId(null);
  31.             //设置付订单id
  32.             subOrderInfo.setParentOrderId(orderId);
  33.             // 赋值仓库Id
  34.             subOrderInfo.setWareId(wareId);
  35.             // 计算子订单的金额: 必须有订单明细
  36.             // 获取到子订单明细
  37.             // 声明一个集合来存储子订单明细
  38.             ArrayList<OrderDetail> orderDetails = new ArrayList<>();
  39.             //获取父订单商品总明细
  40.             List<OrderDetail> orderDetailList = orderInfoOrigin.getOrderDetailList();
  41.             // 表示主主订单明细中获取到子订单的明细
  42.             if (orderDetailList != null && orderDetailList.size() > 0) {
  43.                 for (OrderDetail orderDetail : orderDetailList) {
  44.                     // 获取子订单明细的商品Id
  45.                     for (String skuId : skuIds) {
  46.                         //对比是否是当前仓库的商品,就收集
  47.                         if (Long.parseLong(skuId) == orderDetail.getSkuId().longValue()) {
  48.                             // 将订单明细添加到集合
  49.                             orderDetails.add(orderDetail);
  50.                         }
  51.                     }
  52.                 }
  53.             }
  54.             subOrderInfo.setOrderDetailList(orderDetails);
  55.             // 计算总金额
  56.             subOrderInfo.sumTotalAmount();
  57.             // 保存子订单 submitOrdser(subOrderInfo)
  58.                 saveOrderInfo(subOrderInfo);
  59.             // 将子订单添加到集合中!
  60.             orderInfoArrayList.add(subOrderInfo);
  61.         }
  62.     }
  63.     // 修改原始订单的状态
  64.     updateOrderStatus(orderId, ProcessStatus.SPLIT);
  65.     return orderInfoArrayList;
  66. }
复制代码
 
 拆单接口控制器:OrderApiController:
  1. /**
  2. * 拆单业务
  3. * @param request
  4. * @return
  5. */
  6. @RequestMapping("orderSplit")
  7. public String orderSplit(HttpServletRequest request){
  8.     String orderId = request.getParameter("orderId");
  9.     String wareSkuMap = request.getParameter("wareSkuMap");
  10.     // 拆单:获取到的子订单集合
  11.     List<OrderInfo> subOrderInfoList = orderService.orderSplit(Long.parseLong(orderId),wareSkuMap);
  12.     // 声明一个存储map的集合
  13.     ArrayList<Map> mapArrayList = new ArrayList<>();
  14.     // 生成子订单集合
  15.     for (OrderInfo orderInfo : subOrderInfoList) {
  16.         Map map = orderService.initWareOrder(orderInfo);
  17.         // 添加到集合中!
  18.         mapArrayList.add(map);
  19.     }
  20.     return JSON.toJSONString(mapArrayList);
  21. }
复制代码
前面已经写了: 
 实现类

 


多了两条子订单 


库存系统表: 
订单任务
 

订单任务详情 

(2)取消订单业务增补关闭付出记载


用户没有点击扫码付出,不会调用付出宝的接口,这个时间订单超时后直接关闭订单就行了,当点击扫码付出后,会调用付出宝接口这个时间就会天生PaymentInfo对象,这个时间超时了,还需要关闭付出记载


此时假如用户扫码了,但是没有付出,订单超时了,这个时间还需要关闭付出宝交易记载





关闭订单流程图:




在处理超时订单里:添加代码




在MqConst中添加常量
  1. /**
  2. * 关闭交易
  3. */
  4. public static final String EXCHANGE_DIRECT_PAYMENT_CLOSE = "exchange.direct.payment.close";
  5. public static final String ROUTING_PAYMENT_CLOSE = "payment.close";
  6. //队列
  7. public static final String QUEUE_PAYMENT_CLOSE  = "queue.payment.close";
复制代码
根据业务进行发送1或2,2是有付出记载 


在取消订单实现类中发送消息关闭交易
更改接口

2是有付出记载,才发送消息

  1. @Override
  2. public void execExpiredOrder(Long orderId) {
  3.     // orderInfo
  4.     updateOrderStatus(orderId, ProcessStatus.CLOSED);
  5.       rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_CLOSE, MqConst.ROUTING_PAYMENT_CLOSE, orderId);
  6. }
复制代码
service-payment模块接收消息

编写消费者
  1. package com.atguigu.gmall.payment.receiver;
  2. @Component
  3. public class PaymentReceiver {
  4.     @Autowired
  5.     private PaymentService paymentService;
  6.     @SneakyThrows
  7.     @RabbitListener(bindings = @QueueBinding(
  8.             value = @Queue(value = MqConst.QUEUE_PAYMENT_CLOSE,durable = "true"),
  9.             exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_PAYMENT_CLOSE),
  10.             key = {MqConst.ROUTING_PAYMENT_CLOSE}
  11.     ))
  12.     public void closePayment(Long orderId , Message message, Channel channel){
  13.         if (null != orderId){
  14.             // 关闭交易
  15.             paymentService.closePayment(orderId);
  16.         }
  17.         // 手动ack
  18.         channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
  19.     }
  20. }
复制代码
编写关闭交易记载接口与实现类
  1. PaymentService
复制代码
  1. /**
  2. * 关闭过期交易记录
  3. * @param orderId
  4. */
  5. void closePayment(Long orderId);
复制代码
  1. @Override
  2. public void closePayment(Long orderId) {
  3.     // 设置关闭交易记录的条件  118
  4.     QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();
  5.     paymentInfoQueryWrapper.eq("order_id",orderId);
  6.     // 如果当前的交易记录不存在,则不更新交易记录
  7.     Integer count = paymentInfoMapper.selectCount(paymentInfoQueryWrapper);
  8.     if (null == count || count.intValue()==0) return;
  9.     // 在关闭支付宝交易之前。还需要关闭paymentInfo
  10.     PaymentInfo paymentInfo = new PaymentInfo();
  11.     paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());
  12.     paymentInfoMapper.update(paymentInfo,paymentInfoQueryWrapper);
  13. }
复制代码
提交订单超时后会关闭订单 

(3)付出宝关闭交易

  1. AlipayService接口
复制代码
  1. /***
  2. * 关闭交易
  3. * @param orderId
  4. * @return
  5. */
  6. Boolean closePay(Long orderId);
复制代码
编写实现类
  1. @SneakyThrows
  2. @Override
  3. public Boolean closePay(Long orderId) {
  4.     OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
  5.     AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
  6.     HashMap<String, Object> map = new HashMap<>();
  7.     // map.put("trade_no",paymentInfo.getTradeNo()); // 从paymentInfo 中获取!
  8.         map.put("out_trade_no",orderInfo.getOutTradeNo());
  9.     map.put("operator_id","YX01");
  10.     request.setBizContent(JSON.toJSONString(map));
  11.     AlipayTradeCloseResponse response = alipayClient.execute(request);
  12.     if(response.isSuccess()){
  13.         System.out.println("调用成功");
  14.         return true;
  15.     } else {
  16.         System.out.println("调用失败");
  17.         return false;
  18.     }
  19. }
复制代码
编写控制器AlipayController :
  1. http://localhost:8205/api/payment/alipay/closePay/25
  2. // 根据订单Id关闭订单
  3. @GetMapping("closePay/{orderId}")
  4. @ResponseBody
  5. public Boolean closePay(@PathVariable Long orderId){
  6.     Boolean aBoolean = alipayService.closePay(orderId);
  7.     return aBoolean;
  8. }
复制代码


 


(4)查询付出交易记载

编写接口:AlipayService
  1. /**
  2. * 根据订单查询是否支付成功!
  3.   * @param orderId
  4. * @return
  5. */
  6. Boolean checkPayment(Long orderId);
复制代码
编写实现类
  1. @SneakyThrows
  2. @Override
  3. public Boolean checkPayment(Long orderId) {
  4.     // 根据订单Id 查询订单信息
  5.     OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
  6.     AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
  7.     HashMap<String, Object> map = new HashMap<>();
  8.     map.put("out_trade_no",orderInfo.getOutTradeNo());
  9.     // 根据out_trade_no 查询交易记录
  10.     request.setBizContent(JSON.toJSONString(map));
  11.     AlipayTradeQueryResponse response = alipayClient.execute(request);
  12.     if(response.isSuccess()){
  13.         System.out.println("调用成功");
  14.         return true;
  15.     } else {
  16.         System.out.println("调用失败")
  17.         return false;
  18.     }
  19. }
复制代码
 编写控制器
  1. // 查看是否有交易记录
  2. @RequestMapping("checkPayment/{orderId}")
  3. @ResponseBody
  4. public Boolean checkPayment(@PathVariable Long orderId){
  5.     // 调用退款接口
  6.     boolean flag = alipayService.checkPayment(orderId);
  7.     return flag;
  8. }
复制代码



没有付出返回false 


付出后返回true 



在AlipayController 添加查询PaymentInfo 数据接口
查询付出记载
  1. @GetMapping("getPaymentInfo/{outTradeNo}")
  2. @ResponseBody
  3. public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo){
  4.     PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
  5.     if (null!=paymentInfo){
  6.         return paymentInfo;
  7.     }
  8.     return null;
  9. }
复制代码

 (5)PaymentFeignClient 长途接口

创建service-payment-client

  1. package com.atguigu.gmall.payment.client;
  2. @FeignClient(value = "service-payment",fallback = PaymentDegradeFeignClient.class)
  3. public interface PaymentFeignClient {
  4.     @GetMapping("api/payment/alipay/closePay/{orderId}")
  5.     Boolean closePay(@PathVariable Long orderId);
  6.     @GetMapping("api/payment/alipay/checkPayment/{orderId}")
  7.     Boolean checkPayment(@PathVariable Long orderId);
  8.     @GetMapping("api/payment/alipay/getPaymentInfo/{outTradeNo}")
  9.     PaymentInfo getPaymentInfo(@PathVariable String outTradeNo);
  10. }
复制代码
PaymentDegradeFeignClient实现类 
  1. @Component
  2. public class PaymentDegradeFeignClient implements PaymentFeignClient {
  3.     @Override<dependency>
  4.     <groupId>com.atguigu.gmall</groupId>
  5.     <artifactId>service-payment-client</artifactId>
  6.     <version>1.0</version>
  7. </dependency>
  8.     public Boolean closePay(Long orderId) {
  9.         return null;
  10.     }
  11.     @Override
  12.     public Boolean checkPayment(Long orderId) {
  13.         return null;
  14.     }
  15.     @Override
  16.     public PaymentInfo getPaymentInfo(String outTradeNo) {
  17.         return null;
  18.     }
  19.    
  20. }
复制代码
(6)整合关闭过期订单 

在订单service-order项目中添加依赖
  1. <dependency>
  2.     <groupId>com.atguigu.gmall</groupId>
  3.     <artifactId>service-payment-client</artifactId>
  4.     <version>1.0</version>
  5. </dependency>
复制代码
OrderReceiver 整合代码
  1. 接口:OrderService
复制代码
  1. /**
  2. * 更新过期订单
  3. * @param orderId
  4. * @param flag
  5. */
  6. void execExpiredOrder(Long orderId,String flag);
复制代码
  1. @Override
  2. public void execExpiredOrder(Long orderId,String flag) {
  3.     // 调用方法 状态
  4.     updateOrderStatus(orderId,ProcessStatus.CLOSED);
  5.     //2代表支付宝有交易记录就是扫码了没有支付
  6.     if ("2".equals(flag)){
  7.         // 发送消息队列,关闭支付宝的交易记录。
  8.         rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_CLOSE,MqConst.ROUTING_PAYMENT_CLOSE,orderId);
  9.     }
  10. }
复制代码
 
  1. @Autowired
  2. private RabbitService rabbitService;
  3. @Autowired
  4. private PaymentFeignClient paymentFeignClient;
  5. //  监听消息
  6. @SneakyThrows
  7. @RabbitListener(queues = MqConst.QUEUE_ORDER_CANCEL)
  8. public void orderCancel(Long orderId, Message message, Channel channel){
  9.     try {
  10.         //  判断订单id 是否存在!
  11.         if (orderId!=null){
  12.             //  根据订单Id 查询订单对象
  13.             OrderInfo orderInfo = orderService.getById(orderId);
  14.             //  判断
  15.             if(orderInfo!=null && "UNPAID".equals(orderInfo.getOrderStatus()) && "UNPAID".equals(orderInfo.getProcessStatus())){
  16.                 //  关闭过期订单! 还需要关闭对应的 paymentInfo ,还有alipay.
  17.                 //  orderService.execExpiredOrder(orderId);
  18.                 //  查询支付记录信息paymentInfo -远程调用是否存在!
  19.                 PaymentInfo paymentInfo = paymentFeignClient.getPaymentInfo(orderInfo.getOutTradeNo());
  20.                 //  判断 用户点击了扫码支付
  21.                 if(paymentInfo!=null && "UNPAID".equals(paymentInfo.getPaymentStatus())){
  22.                     //  查看是否有支付宝交易记录!
  23.                     Boolean flag = paymentFeignClient.checkPayment(orderId);
  24.                     //  判断
  25.                     if (flag){
  26.                         //  flag = true , 有支付宝记录
  27.                         //  调用关闭接口! 扫码未支付这样才能关闭成功!
  28.                         Boolean result = paymentFeignClient.closePay(orderId);
  29.                         //  判断
  30.                         if (result){
  31.                             //  result = true; 关闭成功!未付款!需要关闭orderInfo, paymentInfo,Alipay
  32.                             orderService.execExpiredOrder(orderId,"2");
  33.                         }else {
  34.                             //  result = false; 表示付款!
  35.                             //  说明已经付款了! 正常付款成功都会走异步通知!
  36.                         }
  37.                     }else {
  38.                         //  没有交易记录,不需要关闭支付!  需要关闭orderInfo, paymentInfo
  39.                           //关闭订单,关闭支付记录
  40.                         orderService.execExpiredOrder(orderId,"2");
  41.                     }
  42.                 }else {
  43.                     //  只关闭订单orderInfo!
  44.                     orderService.execExpiredOrder(orderId,"1");
  45.                 }
  46.             }
  47.         }
  48.         
  49.     } catch (Exception e) {
  50.         //  写入日志...
  51.         e.printStackTrace();
  52.     }
  53.     //  手动确认
  54.     channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
  55. }
复制代码

不进行付出 




 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

乌市泽哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表