目录:
(1)拆单接口
(2)取消订单业务增补关闭付出记载
(3)付出宝关闭交易
(4)查询付出交易记载
(5)PaymentFeignClient 长途接口
(6)整合关闭过期订单
(1)拆单接口
堆栈表:不是同一个堆栈
在service_order模块
订单实现拆单接口OrderService
- List<OrderInfo> orderSplit(Long orderId, String wareSkuMap);
复制代码
拆单接口实现类OrderServiceImpl
- @Override
- @Transactional
- public List<OrderInfo> orderSplit(Long orderId, String wareSkuMap) {
- ArrayList<OrderInfo> orderInfoArrayList = new ArrayList<>();
- /*
- 1. 先获取到原始订单 107
- 2. 将wareSkuMap 转换为我们能操作的对象 [{"wareId":"1","skuIds":["2","10"]},{"wareId":"2","skuIds":["3"]}]
- 方案一:class Param{
- private String wareId;
- private List<String> skuIds;
- }
- 方案二:看做一个Map mpa.put("wareId",value); map.put("skuIds",value)
- 3. 创建一个新的子订单 108 109 。。。
- 4. 给子订单赋值
- 5. 保存子订单到数据库
- 6. 修改原始订单的状态
- 7. 测试
- */
- //获取父订单
- OrderInfo orderInfoOrigin = getOrderInfoById(orderId);
- List<Map> maps = JSON.parseArray(wareSkuMap, Map.class);
- if (maps != null) {
- for (Map map : maps) {
- String wareId = (String) map.get("wareId");
- List<String> skuIds = (List<String>) map.get("skuIds");
- OrderInfo subOrderInfo = new OrderInfo();
- // 属性拷贝
- BeanUtils.copyProperties(orderInfoOrigin, subOrderInfo);
- // 防止主键冲突
- subOrderInfo.setId(null);
- //设置付订单id
- subOrderInfo.setParentOrderId(orderId);
- // 赋值仓库Id
- subOrderInfo.setWareId(wareId);
- // 计算子订单的金额: 必须有订单明细
- // 获取到子订单明细
- // 声明一个集合来存储子订单明细
- ArrayList<OrderDetail> orderDetails = new ArrayList<>();
- //获取父订单商品总明细
- List<OrderDetail> orderDetailList = orderInfoOrigin.getOrderDetailList();
- // 表示主主订单明细中获取到子订单的明细
- if (orderDetailList != null && orderDetailList.size() > 0) {
- for (OrderDetail orderDetail : orderDetailList) {
- // 获取子订单明细的商品Id
- for (String skuId : skuIds) {
- //对比是否是当前仓库的商品,就收集
- if (Long.parseLong(skuId) == orderDetail.getSkuId().longValue()) {
- // 将订单明细添加到集合
- orderDetails.add(orderDetail);
- }
- }
- }
- }
- subOrderInfo.setOrderDetailList(orderDetails);
- // 计算总金额
- subOrderInfo.sumTotalAmount();
- // 保存子订单 submitOrdser(subOrderInfo)
- saveOrderInfo(subOrderInfo);
- // 将子订单添加到集合中!
- orderInfoArrayList.add(subOrderInfo);
- }
- }
- // 修改原始订单的状态
- updateOrderStatus(orderId, ProcessStatus.SPLIT);
- return orderInfoArrayList;
- }
复制代码
拆单接口控制器:OrderApiController:
- /**
- * 拆单业务
- * @param request
- * @return
- */
- @RequestMapping("orderSplit")
- public String orderSplit(HttpServletRequest request){
- String orderId = request.getParameter("orderId");
- String wareSkuMap = request.getParameter("wareSkuMap");
- // 拆单:获取到的子订单集合
- List<OrderInfo> subOrderInfoList = orderService.orderSplit(Long.parseLong(orderId),wareSkuMap);
- // 声明一个存储map的集合
- ArrayList<Map> mapArrayList = new ArrayList<>();
- // 生成子订单集合
- for (OrderInfo orderInfo : subOrderInfoList) {
- Map map = orderService.initWareOrder(orderInfo);
- // 添加到集合中!
- mapArrayList.add(map);
- }
- return JSON.toJSONString(mapArrayList);
- }
复制代码 前面已经写了:
实现类
多了两条子订单
库存系统表:
订单任务
订单任务详情
(2)取消订单业务增补关闭付出记载
用户没有点击扫码付出,不会调用付出宝的接口,这个时间订单超时后直接关闭订单就行了,当点击扫码付出后,会调用付出宝接口这个时间就会天生PaymentInfo对象,这个时间超时了,还需要关闭付出记载
此时假如用户扫码了,但是没有付出,订单超时了,这个时间还需要关闭付出宝交易记载
关闭订单流程图:
在处理超时订单里:添加代码
在MqConst中添加常量
- /**
- * 关闭交易
- */
- public static final String EXCHANGE_DIRECT_PAYMENT_CLOSE = "exchange.direct.payment.close";
- public static final String ROUTING_PAYMENT_CLOSE = "payment.close";
- //队列
- public static final String QUEUE_PAYMENT_CLOSE = "queue.payment.close";
复制代码 根据业务进行发送1或2,2是有付出记载
在取消订单实现类中发送消息关闭交易
更改接口
2是有付出记载,才发送消息
- @Override
- public void execExpiredOrder(Long orderId) {
- // orderInfo
- updateOrderStatus(orderId, ProcessStatus.CLOSED);
- rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_CLOSE, MqConst.ROUTING_PAYMENT_CLOSE, orderId);
- }
复制代码 service-payment模块接收消息
编写消费者
- package com.atguigu.gmall.payment.receiver;
- @Component
- public class PaymentReceiver {
- @Autowired
- private PaymentService paymentService;
- @SneakyThrows
- @RabbitListener(bindings = @QueueBinding(
- value = @Queue(value = MqConst.QUEUE_PAYMENT_CLOSE,durable = "true"),
- exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_PAYMENT_CLOSE),
- key = {MqConst.ROUTING_PAYMENT_CLOSE}
- ))
- public void closePayment(Long orderId , Message message, Channel channel){
- if (null != orderId){
- // 关闭交易
- paymentService.closePayment(orderId);
- }
- // 手动ack
- channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
- }
- }
复制代码 编写关闭交易记载接口与实现类
- /**
- * 关闭过期交易记录
- * @param orderId
- */
- void closePayment(Long orderId);
复制代码- @Override
- public void closePayment(Long orderId) {
- // 设置关闭交易记录的条件 118
- QueryWrapper<PaymentInfo> paymentInfoQueryWrapper = new QueryWrapper<>();
- paymentInfoQueryWrapper.eq("order_id",orderId);
- // 如果当前的交易记录不存在,则不更新交易记录
- Integer count = paymentInfoMapper.selectCount(paymentInfoQueryWrapper);
- if (null == count || count.intValue()==0) return;
- // 在关闭支付宝交易之前。还需要关闭paymentInfo
- PaymentInfo paymentInfo = new PaymentInfo();
- paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());
- paymentInfoMapper.update(paymentInfo,paymentInfoQueryWrapper);
- }
复制代码 提交订单超时后会关闭订单
(3)付出宝关闭交易
- /***
- * 关闭交易
- * @param orderId
- * @return
- */
- Boolean closePay(Long orderId);
复制代码 编写实现类
- @SneakyThrows
- @Override
- public Boolean closePay(Long orderId) {
- OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
- AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
- HashMap<String, Object> map = new HashMap<>();
- // map.put("trade_no",paymentInfo.getTradeNo()); // 从paymentInfo 中获取!
- map.put("out_trade_no",orderInfo.getOutTradeNo());
- map.put("operator_id","YX01");
- request.setBizContent(JSON.toJSONString(map));
- AlipayTradeCloseResponse response = alipayClient.execute(request);
- if(response.isSuccess()){
- System.out.println("调用成功");
- return true;
- } else {
- System.out.println("调用失败");
- return false;
- }
- }
复制代码 编写控制器AlipayController :
- http://localhost:8205/api/payment/alipay/closePay/25
- // 根据订单Id关闭订单
- @GetMapping("closePay/{orderId}")
- @ResponseBody
- public Boolean closePay(@PathVariable Long orderId){
- Boolean aBoolean = alipayService.closePay(orderId);
- return aBoolean;
- }
复制代码
(4)查询付出交易记载
编写接口:AlipayService
- /**
- * 根据订单查询是否支付成功!
- * @param orderId
- * @return
- */
- Boolean checkPayment(Long orderId);
复制代码 编写实现类
- @SneakyThrows
- @Override
- public Boolean checkPayment(Long orderId) {
- // 根据订单Id 查询订单信息
- OrderInfo orderInfo = orderFeignClient.getOrderInfo(orderId);
- AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
- HashMap<String, Object> map = new HashMap<>();
- map.put("out_trade_no",orderInfo.getOutTradeNo());
- // 根据out_trade_no 查询交易记录
- request.setBizContent(JSON.toJSONString(map));
- AlipayTradeQueryResponse response = alipayClient.execute(request);
- if(response.isSuccess()){
- System.out.println("调用成功");
- return true;
- } else {
- System.out.println("调用失败")
- return false;
- }
- }
复制代码 编写控制器
- // 查看是否有交易记录
- @RequestMapping("checkPayment/{orderId}")
- @ResponseBody
- public Boolean checkPayment(@PathVariable Long orderId){
- // 调用退款接口
- boolean flag = alipayService.checkPayment(orderId);
- return flag;
- }
复制代码
没有付出返回false
付出后返回true
在AlipayController 添加查询PaymentInfo 数据接口
查询付出记载
- @GetMapping("getPaymentInfo/{outTradeNo}")
- @ResponseBody
- public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo){
- PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
- if (null!=paymentInfo){
- return paymentInfo;
- }
- return null;
- }
复制代码
(5)PaymentFeignClient 长途接口
创建service-payment-client
- package com.atguigu.gmall.payment.client;
- @FeignClient(value = "service-payment",fallback = PaymentDegradeFeignClient.class)
- public interface PaymentFeignClient {
- @GetMapping("api/payment/alipay/closePay/{orderId}")
- Boolean closePay(@PathVariable Long orderId);
- @GetMapping("api/payment/alipay/checkPayment/{orderId}")
- Boolean checkPayment(@PathVariable Long orderId);
- @GetMapping("api/payment/alipay/getPaymentInfo/{outTradeNo}")
- PaymentInfo getPaymentInfo(@PathVariable String outTradeNo);
- }
复制代码 PaymentDegradeFeignClient实现类
- @Component
- public class PaymentDegradeFeignClient implements PaymentFeignClient {
- @Override<dependency>
- <groupId>com.atguigu.gmall</groupId>
- <artifactId>service-payment-client</artifactId>
- <version>1.0</version>
- </dependency>
- public Boolean closePay(Long orderId) {
- return null;
- }
- @Override
- public Boolean checkPayment(Long orderId) {
- return null;
- }
- @Override
- public PaymentInfo getPaymentInfo(String outTradeNo) {
- return null;
- }
-
- }
复制代码 (6)整合关闭过期订单
在订单service-order项目中添加依赖
- <dependency>
- <groupId>com.atguigu.gmall</groupId>
- <artifactId>service-payment-client</artifactId>
- <version>1.0</version>
- </dependency>
复制代码 OrderReceiver 整合代码
- /**
- * 更新过期订单
- * @param orderId
- * @param flag
- */
- void execExpiredOrder(Long orderId,String flag);
复制代码- @Override
- public void execExpiredOrder(Long orderId,String flag) {
- // 调用方法 状态
- updateOrderStatus(orderId,ProcessStatus.CLOSED);
- //2代表支付宝有交易记录就是扫码了没有支付
- if ("2".equals(flag)){
- // 发送消息队列,关闭支付宝的交易记录。
- rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_CLOSE,MqConst.ROUTING_PAYMENT_CLOSE,orderId);
- }
- }
复制代码
- @Autowired
- private RabbitService rabbitService;
- @Autowired
- private PaymentFeignClient paymentFeignClient;
- // 监听消息
- @SneakyThrows
- @RabbitListener(queues = MqConst.QUEUE_ORDER_CANCEL)
- public void orderCancel(Long orderId, Message message, Channel channel){
- try {
- // 判断订单id 是否存在!
- if (orderId!=null){
- // 根据订单Id 查询订单对象
- OrderInfo orderInfo = orderService.getById(orderId);
- // 判断
- if(orderInfo!=null && "UNPAID".equals(orderInfo.getOrderStatus()) && "UNPAID".equals(orderInfo.getProcessStatus())){
- // 关闭过期订单! 还需要关闭对应的 paymentInfo ,还有alipay.
- // orderService.execExpiredOrder(orderId);
- // 查询支付记录信息paymentInfo -远程调用是否存在!
- PaymentInfo paymentInfo = paymentFeignClient.getPaymentInfo(orderInfo.getOutTradeNo());
- // 判断 用户点击了扫码支付
- if(paymentInfo!=null && "UNPAID".equals(paymentInfo.getPaymentStatus())){
- // 查看是否有支付宝交易记录!
- Boolean flag = paymentFeignClient.checkPayment(orderId);
- // 判断
- if (flag){
- // flag = true , 有支付宝记录
- // 调用关闭接口! 扫码未支付这样才能关闭成功!
- Boolean result = paymentFeignClient.closePay(orderId);
- // 判断
- if (result){
- // result = true; 关闭成功!未付款!需要关闭orderInfo, paymentInfo,Alipay
- orderService.execExpiredOrder(orderId,"2");
- }else {
- // result = false; 表示付款!
- // 说明已经付款了! 正常付款成功都会走异步通知!
- }
- }else {
- // 没有交易记录,不需要关闭支付! 需要关闭orderInfo, paymentInfo
- //关闭订单,关闭支付记录
- orderService.execExpiredOrder(orderId,"2");
- }
- }else {
- // 只关闭订单orderInfo!
- orderService.execExpiredOrder(orderId,"1");
- }
- }
- }
-
- } catch (Exception e) {
- // 写入日志...
- e.printStackTrace();
- }
- // 手动确认
- channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
- }
复制代码
不进行付出
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |