xiongzhu 4 лет назад
Родитель
Сommit
d996d771fc

+ 3 - 1
src/main/java/com/izouma/nineth/event/CreateOrderEvent.java

@@ -4,10 +4,12 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serializable;
+
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
-public class CreateOrderEvent {
+public class CreateOrderEvent implements Serializable {
     private Long id;
     private Long userId;
     private Long collectionId;

+ 19 - 0
src/main/java/com/izouma/nineth/event/OrderNotifyEvent.java

@@ -0,0 +1,19 @@
+package com.izouma.nineth.event;
+
+import com.izouma.nineth.enums.PayMethod;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderNotifyEvent implements Serializable {
+    private Long          orderId;
+    private PayMethod     payMethod;
+    private String        transactionId;
+    private LocalDateTime time;
+}

+ 30 - 0
src/main/java/com/izouma/nineth/listener/OrderNotifyListener.java

@@ -0,0 +1,30 @@
+package com.izouma.nineth.listener;
+
+import com.izouma.nineth.event.OrderNotifyEvent;
+import com.izouma.nineth.service.OrderService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.spring.annotation.ConsumeMode;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+@AllArgsConstructor
+@RocketMQMessageListener(
+        consumerGroup = "${general.create-order-group}",
+        topic = "${general.create-order-topic}",
+        consumeMode = ConsumeMode.CONCURRENTLY)
+public class OrderNotifyListener implements RocketMQListener<OrderNotifyEvent> {
+    private OrderService orderService;
+
+    @Override
+    public void onMessage(OrderNotifyEvent e) {
+        try {
+            orderService.notifyOrder(e.getOrderId(), e.getPayMethod(), e.getTransactionId());
+        } catch (Exception exception) {
+            log.error("处理订单回调出错 orderId: " + e.getOrderId(), exception);
+        }
+    }
+}

+ 0 - 2
src/main/java/com/izouma/nineth/service/CollectionService.java

@@ -278,7 +278,6 @@ public class CollectionService {
     }
 
     public BlindBoxItem draw(Long collectionId) {
-        log.info("开始盲盒抽卡 {}", collectionId);
         long t = System.currentTimeMillis();
         List<BlindBoxItem> items = blindBoxItemRepo.findByBlindBoxId(collectionId);
 
@@ -330,7 +329,6 @@ public class CollectionService {
         winItem.setStock(winItem.getStock() - 1);
         winItem.setSale(winItem.getSale() + 1);
         blindBoxItemRepo.save(winItem);
-        log.info("盲盒抽卡成功 {}ms", System.currentTimeMillis() - t);
         return winItem;
     }
 

+ 28 - 3
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -15,6 +15,7 @@ import com.github.binarywang.wxpay.service.WxPayService;
 import com.huifu.adapay.core.exception.BaseAdaPayException;
 import com.huifu.adapay.model.AdapayCommon;
 import com.huifu.adapay.model.Payment;
+import com.huifu.adapay.model.Refund;
 import com.izouma.nineth.config.AdapayProperties;
 import com.izouma.nineth.config.AlipayProperties;
 import com.izouma.nineth.config.GeneralProperties;
@@ -414,6 +415,7 @@ public class OrderService {
 
     @Transactional
     public void notifyOrder(Long orderId, PayMethod payMethod, String transactionId) {
+        log.info("订单回调 orderId: {}", orderId);
         Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
         Collection collection = collectionRepo.findById(order.getCollectionId())
                 .orElseThrow(new BusinessException("藏品不存在"));
@@ -424,7 +426,30 @@ public class OrderService {
             order.setTransactionId(transactionId);
             order.setPayMethod(payMethod);
             if (order.getType() == CollectionType.BLIND_BOX) {
-                BlindBoxItem winItem = collectionService.draw(collection.getId());
+                log.info("开始盲盒抽卡 orderId: {}, collectionId: {}", orderId, collection.getId());
+                BlindBoxItem winItem = null;
+                try {
+                    winItem = collectionService.draw(collection.getId());
+                } catch (BusinessException e) {
+                }
+                if (winItem == null) {
+                    log.info("抽卡失败退款 orderId: {}", orderId);
+                    order.setStatus(OrderStatus.CANCELLED);
+                    order.setCancelTime(LocalDateTime.now());
+
+                    Map<String, Object> refundParams = new HashMap<>();
+                    refundParams.put("refund_amt", order.getTotalPrice().setScale(2, RoundingMode.HALF_UP)
+                            .toPlainString());
+                    refundParams.put("refund_order_no", String.valueOf(snowflakeIdWorker.nextId()));
+                    try {
+                        Map<String, Object> response = Refund.create(transactionId, refundParams);
+                    } catch (BaseAdaPayException e) {
+                        e.printStackTrace();
+                    }
+                    orderRepo.save(order);
+                    return;
+                }
+                log.info("抽卡成功 orderId: {}, collectionId: {}, winCollectionId: {}", orderId, collection.getId(), winItem.getCollectionId());
                 order.setWinCollectionId(winItem.getCollectionId());
                 orderRepo.save(order);
                 assetService.createAsset(winItem, user, order.getId(), order.getPrice(), "出售",
@@ -448,9 +473,9 @@ public class OrderService {
             }
             commission(order);
             collectionService.increaseSale(order.getCollectionId(), order.getQty());
-        } else if (order.getStatus() == OrderStatus.CANCELLED) {
+        } else {
+            log.info("订单回调状态错误 {} {}", orderId, order.getStatus());
         }
-
     }
 
     @EventListener

+ 47 - 16
src/main/java/com/izouma/nineth/web/OrderNotifyController.java

@@ -12,7 +12,9 @@ import com.github.kevinsawicki.http.HttpRequest;
 import com.huifu.adapay.core.AdapayCore;
 import com.huifu.adapay.core.util.AdapaySign;
 import com.izouma.nineth.config.AlipayProperties;
+import com.izouma.nineth.config.GeneralProperties;
 import com.izouma.nineth.enums.PayMethod;
+import com.izouma.nineth.event.OrderNotifyEvent;
 import com.izouma.nineth.service.AssetService;
 import com.izouma.nineth.service.GiftOrderService;
 import com.izouma.nineth.service.OrderService;
@@ -20,10 +22,12 @@ import com.izouma.nineth.utils.SnowflakeIdWorker;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.MapUtils;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -42,6 +46,8 @@ public class OrderNotifyController {
     private final AssetService      assetService;
     private final GiftOrderService  giftOrderService;
     private final SnowflakeIdWorker snowflakeIdWorker;
+    private final RocketMQTemplate  rocketMQTemplate;
+    private final GeneralProperties generalProperties;
 
     @PostMapping("/order/alipay")
     @ResponseBody
@@ -133,26 +139,51 @@ public class OrderNotifyController {
         return "ok";
     }
 
+//    @PostMapping("/adapay/order/{orderId}")
+//    @ResponseBody
+//    public void adapayNotify(@PathVariable Long orderId, HttpServletRequest request) {
+//        log.info("adapay notify: \n{}", JSON.toJSONString(request.getParameterMap(), PrettyFormat));
+//        try {
+//            String data = request.getParameter("data");
+//            String sign = request.getParameter("sign");
+//            String type = request.getParameter("type");
+//            if ("payment.succeeded".equals(type)) {
+//                boolean checkSign = AdapaySign.verifySign(data, sign, AdapayCore.PUBLIC_KEY);
+//                log.info("checkSign {}", checkSign);
+//                if (checkSign) {
+//                    JSONObject jsonObject = JSON.parseObject(data);
+//                    String channel = jsonObject.getString("pay_channel");
+//                    String id = jsonObject.getString("id");
+//
+//                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
+//                            new OrderNotifyEvent(orderId, channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY, id, LocalDateTime.now()));
+//
+//                    orderService.notifyOrder(orderId, channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY, id);
+//                }
+//            }
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+
     @PostMapping("/adapay/order/{orderId}")
     @ResponseBody
-    public void adapayNotify(@PathVariable Long orderId, HttpServletRequest request) {
+    public void adapayNotify(@PathVariable Long orderId, HttpServletRequest request) throws Exception {
         log.info("adapay notify: \n{}", JSON.toJSONString(request.getParameterMap(), PrettyFormat));
-        try {
-            String data = request.getParameter("data");
-            String sign = request.getParameter("sign");
-            String type = request.getParameter("type");
-            if ("payment.succeeded".equals(type)) {
-                boolean checkSign = AdapaySign.verifySign(data, sign, AdapayCore.PUBLIC_KEY);
-                log.info("checkSign {}", checkSign);
-                if (checkSign) {
-                    JSONObject jsonObject = JSON.parseObject(data);
-                    String channel = jsonObject.getString("pay_channel");
-                    String id = jsonObject.getString("id");
-                    orderService.notifyOrder(orderId, channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY, id);
-                }
+        String data = request.getParameter("data");
+        String sign = request.getParameter("sign");
+        String type = request.getParameter("type");
+        if ("payment.succeeded".equals(type)) {
+            boolean checkSign = AdapaySign.verifySign(data, sign, AdapayCore.PUBLIC_KEY);
+            log.info("checkSign {}", checkSign);
+            if (checkSign) {
+                JSONObject jsonObject = JSON.parseObject(data);
+                String channel = jsonObject.getString("pay_channel");
+                String id = jsonObject.getString("id");
+
+                rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
+                        new OrderNotifyEvent(orderId, channel.startsWith("wx") ? PayMethod.WEIXIN : PayMethod.ALIPAY, id, LocalDateTime.now()));
             }
-        } catch (Exception e) {
-            e.printStackTrace();
         }
     }
 

+ 6 - 6
src/test/java/com/izouma/nineth/service/AdapayServiceTest.java

@@ -36,12 +36,12 @@ public class AdapayServiceTest extends ApplicationTests {
         ForkJoinPool customThreadPool = new ForkJoinPool(100);
         customThreadPool.submit(() -> {
 
-            List<AdaTrade> list = EasyExcel.read("/Users/drew/Downloads/merTransDetail_0284905900625472_20220107_20220108_1641637419.xlsx")
+            List<AdaTrade> list = EasyExcel.read("/Users/drew/Downloads/merTransDetail_0284905900625472_20220112_20220119_1642583914.xlsx")
                     .head(AdaTrade.class).sheet().doReadSync();
             list = list.parallelStream().filter(adaTrade -> {
                 return adaTrade.get交易金额().equals("1.00")
-                        && orderRepo.findByTransactionId(adaTrade.get订单号()) == null
-                        && giftOrderRepo.findByTransactionId(adaTrade.get订单号()) == null;
+                        && orderRepo.findByTransactionId(adaTrade.get支付流水号()) == null
+                        && giftOrderRepo.findByTransactionId(adaTrade.get支付流水号()) == null;
             }).collect(Collectors.toList());
 
             EasyExcel.write("/Users/drew/Downloads/1.xlsx", AdaTrade.class).sheet("模板").doWrite(list);
@@ -61,7 +61,7 @@ public class AdapayServiceTest extends ApplicationTests {
             refundParams.put("refund_amt", adaTrade.get交易金额());
             refundParams.put("refund_order_no", snowflakeIdWorker.nextId() + "");
             try {
-                Map<String, Object> response = Refund.create(adaTrade.get订单号(), refundParams);
+                Map<String, Object> response = Refund.create(adaTrade.get支付流水号(), refundParams);
             } catch (BaseAdaPayException e) {
                 e.printStackTrace();
             }
@@ -70,13 +70,13 @@ public class AdapayServiceTest extends ApplicationTests {
 
     @Test
     public void verifyRefund() throws BaseAdaPayException {
-        List<AdaTrade> list = EasyExcel.read("/Users/drew/Downloads/1.xlsx")
+        List<AdaTrade> list = EasyExcel.read("/Users/drew/Downloads/2.xlsx")
                 .head(AdaTrade.class).sheet().doReadSync();
         list = list.parallelStream().filter(adaTrade -> {
             boolean success = false;
             try {
                 Map<String, Object> refundParams = new HashMap<>(2);
-                refundParams.put("payment_id", adaTrade.get订单号());
+                refundParams.put("payment_id", adaTrade.get支付流水号());
                 Map<String, Object> refund = Refund.query(refundParams);
                 JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(refund));
                 if ("S".equals(jsonObject.getJSONArray("refunds").getJSONObject(0).getString("trans_status"))) {

+ 16 - 0
src/test/java/com/izouma/nineth/service/OrderServiceTest.java

@@ -45,6 +45,8 @@ public class OrderServiceTest extends ApplicationTests {
     private UserBankCardRepo  userBankCardRepo;
     @Autowired
     private CollectionService collectionService;
+    @Autowired
+    private BlindBoxItemRepo  blindBoxItemRepo;
 
     @Test
     public void create() {
@@ -225,4 +227,18 @@ public class OrderServiceTest extends ApplicationTests {
         });
 
     }
+
+
+    @Test
+    public void asdf() {
+        orderRepo.findByCollectionId(1175138L).stream().filter(o -> o.getStatus() == OrderStatus.FINISH).parallel()
+                .forEach(order -> {
+                    List<Asset> assets = assetRepo.findByOrderId(order.getId());
+                    if (assets.size() > 1) {
+                        for (int i = 1; i < assets.size(); i++) {
+                            assetRepo.delete(assets.get(i));
+                        }
+                    }
+                });
+    }
 }