|
|
@@ -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;
|
|
|
}
|
|
|
}
|
|
|
|