feat(health):新增延时队列处理超时订单
This commit is contained in:
parent
084455fd76
commit
b4d10a7306
@ -6,8 +6,8 @@
|
||||
<groupId>com.jzo2o</groupId>
|
||||
<artifactId>jzo2o-health</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<name>health</name>
|
||||
<description>health</description>
|
||||
<name>jzo2o-health</name>
|
||||
<description>jzo2o-health</description>
|
||||
|
||||
<parent>
|
||||
<artifactId>jzo2o-parent</artifactId>
|
||||
@ -100,4 +100,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
@ -0,0 +1,61 @@
|
||||
package com.jzo2o.health.config;
|
||||
|
||||
import com.jzo2o.health.constant.HealthMqConstants;
|
||||
import com.jzo2o.rabbitmq.config.RabbitMqConfiguration;
|
||||
import org.springframework.amqp.core.*;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* RabbitMQ延时队列
|
||||
* @author JIAN
|
||||
*/
|
||||
@Configuration
|
||||
@Import(RabbitMqConfiguration.class)
|
||||
public class DelayQueueConfiguration {
|
||||
@Bean
|
||||
public Exchange delayExchange() {
|
||||
return ExchangeBuilder
|
||||
.topicExchange(HealthMqConstants.Exchanges.HEALTH_ORDER)
|
||||
.durable(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Queue delayQueueIn() {
|
||||
return QueueBuilder
|
||||
.durable(HealthMqConstants.Queues.DELAY_IN)
|
||||
// 订单默认15分钟超时
|
||||
.ttl((int) TimeUnit.MINUTES.toMillis(15))
|
||||
.deadLetterExchange(HealthMqConstants.Exchanges.HEALTH_ORDER)
|
||||
.deadLetterRoutingKey(HealthMqConstants.RoutingKeys.ORDER_OVERTIME_OUT)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Queue delayQueueOut() {
|
||||
return QueueBuilder.durable(HealthMqConstants.Queues.DELAY_OUT)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Binding bindDelayQueueIn() {
|
||||
return BindingBuilder
|
||||
.bind(delayQueueIn())
|
||||
.to(delayExchange())
|
||||
.with(HealthMqConstants.RoutingKeys.ORDER_OVERTIME_IN)
|
||||
.noargs();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Binding bindDelayQueueOut() {
|
||||
return BindingBuilder
|
||||
.bind(delayQueueOut())
|
||||
.to(delayExchange())
|
||||
.with(HealthMqConstants.RoutingKeys.ORDER_OVERTIME_OUT)
|
||||
.noargs();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.jzo2o.health.constant;
|
||||
|
||||
import com.jzo2o.common.constants.MqConstants;
|
||||
|
||||
/**
|
||||
* 即刻体检MQ常量
|
||||
* @author JIAN
|
||||
*/
|
||||
public interface HealthMqConstants extends MqConstants {
|
||||
interface Exchanges extends MqConstants.Exchanges {
|
||||
String HEALTH_ORDER = "health.exchange.topic.order";
|
||||
}
|
||||
|
||||
interface Queues extends MqConstants.Queues {
|
||||
String DELAY_IN = "health.queue.orders.delay.in";
|
||||
String DELAY_OUT = "health.queue.orders.delay.out";
|
||||
}
|
||||
|
||||
interface RoutingKeys extends MqConstants.RoutingKeys {
|
||||
String ORDER_OVERTIME_IN = "order.overtime.in";
|
||||
String ORDER_OVERTIME_OUT = "order.overtime.out";
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,25 @@
|
||||
package com.jzo2o.health.listener;
|
||||
|
||||
import com.jzo2o.api.trade.TradingApi;
|
||||
import com.jzo2o.api.trade.dto.response.TradingResDTO;
|
||||
import com.jzo2o.api.trade.enums.TradingStateEnum;
|
||||
import com.jzo2o.common.constants.MqConstants;
|
||||
import com.jzo2o.common.constants.UserType;
|
||||
import com.jzo2o.common.expcetions.DBException;
|
||||
import com.jzo2o.common.model.msg.TradeStatusMsg;
|
||||
import com.jzo2o.common.utils.CollUtils;
|
||||
import com.jzo2o.common.utils.JsonUtils;
|
||||
import com.jzo2o.common.utils.ObjectUtils;
|
||||
import com.jzo2o.health.constant.HealthMqConstants;
|
||||
import com.jzo2o.health.constant.TradeConstants;
|
||||
import com.jzo2o.health.enums.OrderPayStatusEnum;
|
||||
import com.jzo2o.health.enums.OrderStatusEnum;
|
||||
import com.jzo2o.health.model.OrderUpdateStatusDTO;
|
||||
import com.jzo2o.health.model.domain.Orders;
|
||||
import com.jzo2o.health.model.domain.OrdersCancelled;
|
||||
import com.jzo2o.health.service.IOrderCancelService;
|
||||
import com.jzo2o.health.service.IOrderCommonService;
|
||||
import com.jzo2o.health.service.IOrderCreateService;
|
||||
import com.jzo2o.health.service.IReservationSettingService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.ExchangeTypes;
|
||||
import org.springframework.amqp.rabbit.annotation.Exchange;
|
||||
@ -37,6 +45,12 @@ public class OrderStatusListener {
|
||||
private IOrderCommonService orderCommonService;
|
||||
@Resource
|
||||
private TransactionTemplate transactionTemplate;
|
||||
@Resource
|
||||
private IOrderCancelService orderCancelService;
|
||||
@Resource
|
||||
private IReservationSettingService reservationSettingService;
|
||||
@Resource
|
||||
private TradingApi tradingApi;
|
||||
|
||||
/**
|
||||
* 接收支付成功信息
|
||||
@ -44,10 +58,10 @@ public class OrderStatusListener {
|
||||
*/
|
||||
@RabbitListener(bindings = @QueueBinding(
|
||||
value = @Queue(name = TradeConstants.MQ_TRADE_QUEUE),
|
||||
exchange = @Exchange(name = MqConstants.Exchanges.TRADE, type = ExchangeTypes.TOPIC),
|
||||
key = MqConstants.RoutingKeys.TRADE_UPDATE_STATUS))
|
||||
exchange = @Exchange(name = HealthMqConstants.Exchanges.TRADE, type = ExchangeTypes.TOPIC),
|
||||
key = HealthMqConstants.RoutingKeys.TRADE_UPDATE_STATUS))
|
||||
public void listenTradeUpdatePayStatusMsg(String msg) {
|
||||
log.info("接收到支付结果状态的消息 ({})-> {}", MqConstants.Queues.ORDERS_TRADE_UPDATE_STATUS, msg);
|
||||
log.info("接收到支付结果状态的消息 ({})-> {}", HealthMqConstants.Queues.ORDERS_TRADE_UPDATE_STATUS, msg);
|
||||
|
||||
List<TradeStatusMsg> msgList = JsonUtils.parseArray(msg).toList(TradeStatusMsg.class);
|
||||
if (CollUtils.isEmpty(msgList)) {
|
||||
@ -76,4 +90,44 @@ public class OrderStatusListener {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@RabbitListener(bindings = @QueueBinding(
|
||||
value = @Queue(name = HealthMqConstants.Queues.DELAY_OUT),
|
||||
exchange = @Exchange(name = HealthMqConstants.Exchanges.HEALTH_ORDER, type = ExchangeTypes.TOPIC),
|
||||
key = HealthMqConstants.RoutingKeys.ORDER_OVERTIME_OUT))
|
||||
public void handleOverTimeOrder(String msg) {
|
||||
Long orderId = Long.parseLong(msg);
|
||||
if (ObjectUtils.isEmpty(orderId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Orders order = orderCommonService.getById(orderId);
|
||||
if (ObjectUtils.isEmpty(order)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (order.getOrderStatus() == OrderStatusEnum.NO_PAY && order.getPayStatus() == OrderPayStatusEnum.NO_PAY) {
|
||||
Long tradingOrderNo = order.getTradingOrderNo();
|
||||
if (ObjectUtils.isNotEmpty(tradingOrderNo)) {
|
||||
// 再次请求防止已支付
|
||||
TradingResDTO tradingResDTO = tradingApi.findTradResultByTradingOrderNo(tradingOrderNo);
|
||||
if (ObjectUtils.isNotEmpty(tradingResDTO) && tradingResDTO.getTradingState() == TradingStateEnum.YJS) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 事务更新数据表(取消订单)
|
||||
transactionTemplate.executeWithoutResult(status -> {
|
||||
orderCancelService.cancelOrder(OrdersCancelled.builder()
|
||||
.id(orderId)
|
||||
.cancelTime(LocalDateTime.now())
|
||||
.cancelReason("订单超时自动取消")
|
||||
.cancellerType(UserType.SYSTEM)
|
||||
.build());
|
||||
|
||||
// 已预约人数 - 1
|
||||
reservationSettingService.plusReservationCount(order.getReservationDate(), -1);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -30,6 +30,7 @@ import com.jzo2o.health.model.dto.response.OrdersPayResDTO;
|
||||
import com.jzo2o.health.model.dto.response.PlaceOrderResDTO;
|
||||
import com.jzo2o.health.properties.TradeProperties;
|
||||
import com.jzo2o.health.service.*;
|
||||
import com.jzo2o.rabbitmq.client.RabbitClient;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -64,6 +65,8 @@ public class OrderCreateServiceImpl extends ServiceImpl<OrdersMapper, Orders> im
|
||||
private RedisTemplate<String, Long> redisTemplate;
|
||||
@Resource
|
||||
private TransactionTemplate transactionTemplate;
|
||||
@Resource
|
||||
private RabbitClient rabbitClient;
|
||||
|
||||
/**
|
||||
* 生成订单号(2位年+2位月+2位日+13位序号)
|
||||
@ -125,6 +128,9 @@ public class OrderCreateServiceImpl extends ServiceImpl<OrdersMapper, Orders> im
|
||||
reservationSettingService.plusReservationCount(placeOrderReqDTO.getReservationDate(), 1);
|
||||
});
|
||||
|
||||
// 发送消息到延时队列处理超时订单(发送检测的订单id)
|
||||
rabbitClient.sendMsg("health.exchange.topic.order", "order.overtime.in", orderId.toString());
|
||||
|
||||
return new PlaceOrderResDTO(orderId);
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +100,7 @@ public class ReservationSettingServiceImpl extends ServiceImpl<ReservationSettin
|
||||
|
||||
@Override
|
||||
public void plusReservationCount(LocalDate time, Integer count) {
|
||||
if (SqlHelper.retBool(baseMapper.plusReservationCount(time, count))) {
|
||||
if (!SqlHelper.retBool(baseMapper.plusReservationCount(time, count))) {
|
||||
throw new CommonException("预约人数已满不能预约");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user