Explorar o código

订单接单,退款超时监控增加逻辑,配置系数

jyc hai 3 semanas
pai
achega
0be659e7c5

+ 93 - 11
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/OrderExpirationServiceImpl.java

@@ -1,20 +1,30 @@
 package shop.alien.lawyer.service.impl;
 
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import shop.alien.entity.store.LawyerConsultationOrder;
+import shop.alien.entity.store.LifeNotice;
+import shop.alien.entity.store.vo.WebSocketVo;
 import shop.alien.lawyer.config.BaseRedisService;
+import shop.alien.lawyer.config.WebSocketProcess;
+import shop.alien.lawyer.controller.AliController;
 import shop.alien.lawyer.listener.RedisKeyExpirationHandler;
 import shop.alien.lawyer.service.OrderExpirationService;
 import shop.alien.mapper.LawyerConsultationOrderMapper;
+import shop.alien.mapper.LifeNoticeMapper;
+import shop.alien.mapper.LifeUserMapper;
 
 
 import javax.annotation.PostConstruct;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 
 /**
  * 訂單過期處理服務實現類
@@ -36,6 +46,10 @@ public class OrderExpirationServiceImpl implements OrderExpirationService, Comma
     private final BaseRedisService redisService;
     private final RedisKeyExpirationHandler expirationHandler;
     private final LawyerConsultationOrderMapper orderMapper;
+    private final AliController aliController;
+    private final LifeNoticeMapper lifeNoticeMapper;
+    private final LifeUserMapper lifeUserMapper;
+    private final WebSocketProcess webSocketProcess;
 
     /**
      * Redis key前綴:訂單支付超時
@@ -58,6 +72,11 @@ public class OrderExpirationServiceImpl implements OrderExpirationService, Comma
     private static final long DEFAULT_TIMEOUT_SECONDS = 30 * 60;
 
     /**
+     * 系统发送者ID
+     */
+    private static final String SYSTEM_SENDER_ID = "system";
+
+    /**
      * 初始化時註冊訂單支付超時處理器
      */
     @PostConstruct
@@ -68,11 +87,11 @@ public class OrderExpirationServiceImpl implements OrderExpirationService, Comma
 
         // 註冊订单待接单超时處理器
         expirationHandler.registerHandler(ORDER_ACCEPT_TIMEOUT_PREFIX, this::handleRefundOrderKey);
-        log.info("訂單支付超時處理器註冊完成,前綴: {}", ORDER_ACCEPT_TIMEOUT_PREFIX);
+        log.info("訂單接单超時處理器註冊完成,前綴: {}", ORDER_ACCEPT_TIMEOUT_PREFIX);
 
         // 註冊訂單退款超時處理器
         expirationHandler.registerHandler(ORDER_REFUND_TIMEOUT_PREFIX, this::handleRefundOrderKey);
-        log.info("訂單支付超時處理器註冊完成,前綴: {}", ORDER_REFUND_TIMEOUT_PREFIX);
+        log.info("訂單退款超時處理器註冊完成,前綴: {}", ORDER_REFUND_TIMEOUT_PREFIX);
     }
 
     @Override
@@ -107,14 +126,45 @@ public class OrderExpirationServiceImpl implements OrderExpirationService, Comma
     private void handleRefundOrderKey(String expiredKey) {
         try {
             // 從key中提取訂單ID
-            String orderNo = expiredKey.replace(ORDER_PAYMENT_TIMEOUT_PREFIX, "");
+            String orderNo = "";
+            String refundReason = "";
+            String title = "";
+            String message = "";
+            if (expiredKey.contains(ORDER_ACCEPT_TIMEOUT_PREFIX)) {
+                orderNo = expiredKey.replace(ORDER_ACCEPT_TIMEOUT_PREFIX, "");
+                refundReason = "律师未接单超時退款";
+                title = "未接单通知";
+                message = "您的编号为" + orderNo + "的订单已到48小时未被接单,订单金额将在1-3个工作日原路返还,请注意查收。";
+            }
+            if (expiredKey.contains(ORDER_REFUND_TIMEOUT_PREFIX)) {
+                orderNo = expiredKey.replace(ORDER_REFUND_TIMEOUT_PREFIX, "");
+                refundReason = "申请退款超时后退款";
+                title = "申请退款通知";
+                message = "您的编号为" + orderNo + "的订单,申请退款的信息已提交给律师,等待律师同意。律师同意或48小时未处理,系统会将订单金额原路返还,请注意查收。";
+            }
 
-            log.info("檢測到訂單支付超時,訂單no: {}", orderNo);
+            // 查詢訂單
+            LambdaQueryWrapper<LawyerConsultationOrder> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(LawyerConsultationOrder::getOrderNumber, orderNo).last("LIMIT 1");
+            LawyerConsultationOrder order = orderMapper.selectOne(queryWrapper);
 
-            // 處理訂單支付超時
-            handleOrderPaymentTimeout(orderNo);
+            log.info("檢測到有訂單需要退款,訂單no: {}", orderNo);
+
+            // 處理訂單退款
+            aliController.processRefund(order.getAlipayNo(),  new BigDecimal(order.getOrderAmount()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString(), refundReason,"");
+
+            log.info("訂單退款成功,訂單no: {}", orderNo);
+
+            //通知
+            LifeNotice lifeNotice = buildLifeNotice(order, title, message);
+            WebSocketVo webSocketVo = buildWebSocketVo(lifeNotice);
+
+            lifeNoticeMapper.insert(lifeNotice);
+            webSocketProcess.sendMessage(lifeNotice.getReceiverId(), JSONObject.from(webSocketVo).toJSONString());
+
+            log.info("系统通知发送成功,訂單no: {}", orderNo);
         } catch (Exception e) {
-            log.error("處理過期訂單key失敗,key: {}", expiredKey, e);
+            log.error("處理有訂單需要退款key失敗,key: {}", expiredKey, e);
         }
     }
 
@@ -189,7 +239,7 @@ public class OrderExpirationServiceImpl implements OrderExpirationService, Comma
         // 當key過期時,會觸發RedisKeyExpirationListener
         redisService.setString(key, String.valueOf(orderNumber), timeout);
 
-        log.info("設置訂單支付超時監聽,訂單NO: {}, 超時時間: {}秒, key: {}", orderNumber, timeout, key);
+        log.info("設置訂單接单超時監聽,訂單NO: {}, 超時時間: {}秒, key: {}", orderNumber, timeout, key);
     }
 
     @Override
@@ -206,7 +256,7 @@ public class OrderExpirationServiceImpl implements OrderExpirationService, Comma
         // 當key過期時,會觸發RedisKeyExpirationListener
         redisService.setString(key, String.valueOf(orderNumber), timeout);
 
-        log.info("設置訂單支付超時監聽,訂單NO: {}, 超時時間: {}秒, key: {}", orderNumber, timeout, key);
+        log.info("設置訂單退款超時監聽,訂單NO: {}, 超時時間: {}秒, key: {}", orderNumber, timeout, key);
     }
 
     /**
@@ -234,7 +284,7 @@ public class OrderExpirationServiceImpl implements OrderExpirationService, Comma
         String key = ORDER_ACCEPT_TIMEOUT_PREFIX + orderNumber;
         redisService.delete(key);
 
-        log.info("取消訂單支付超時監聽,訂單ID: {}, key: {}", orderNumber, key);
+        log.info("取消訂單接单超時監聽,訂單ID: {}, key: {}", orderNumber, key);
     }
 
     @Override
@@ -246,7 +296,39 @@ public class OrderExpirationServiceImpl implements OrderExpirationService, Comma
         String key = ORDER_REFUND_TIMEOUT_PREFIX + orderNumber;
         redisService.delete(key);
 
-        log.info("取消訂單支付超時監聽,訂單ID: {}, key: {}", orderNumber, key);
+        log.info("取消訂單退款超時監聽,訂單ID: {}, key: {}", orderNumber, key);
+    }
+
+    /**
+     * 构建WebSocket消息对象
+     *
+     * @param lifeNotice 通知对象
+     * @return WebSocketVo对象
+     */
+    private WebSocketVo buildWebSocketVo(LifeNotice lifeNotice) {
+        WebSocketVo webSocketVo = new WebSocketVo();
+        webSocketVo.setSenderId(SYSTEM_SENDER_ID);
+        webSocketVo.setReceiverId(lifeNotice.getReceiverId());
+        webSocketVo.setCategory("notice");
+        webSocketVo.setNoticeType("1");
+        webSocketVo.setIsRead(0);
+        webSocketVo.setText(JSONObject.from(lifeNotice).toJSONString());
+        return webSocketVo;
+    }
+
+    private LifeNotice buildLifeNotice(LawyerConsultationOrder lawyerConsultationOrder,String title,String message){
+        LifeNotice lifeNotice = new LifeNotice();
+        lifeNotice.setSenderId(SYSTEM_SENDER_ID);
+        lifeNotice.setBusinessId(lawyerConsultationOrder.getId());
+        lifeNotice.setTitle(title);
+        lifeNotice.setReceiverId("lawyer_" + lifeUserMapper.selectById(lawyerConsultationOrder.getClientUserId()).getUserPhone());
+
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("message", message);
+        lifeNotice.setContext(jsonObject.toJSONString());
+        lifeNotice.setNoticeType(1);
+
+        return lifeNotice;
     }
 }