From 0d7648b8cc14fe8833d3a2028b266e3f1f6098a3 Mon Sep 17 00:00:00 2001 From: xc-yjs Date: Wed, 11 Sep 2024 18:25:00 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=20=E6=9B=B4=E6=96=B0=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/nla/common/model/OrderMessage.java | 16 +++ .../cn/nla/order/config/RabbitMQConfig.java | 103 ++++++++++++++++++ .../order/mapper/ProductOrderItemMapper.java | 7 ++ .../model/entity/ProductOrderEntity.java | 2 +- .../service/impl/ProductOrderServiceImpl.java | 84 ++++++++++++-- .../src/main/resources/application.yml | 28 +++++ .../mapper/ProductOrderItemMapper.xml | 43 ++++++-- 7 files changed, 264 insertions(+), 19 deletions(-) create mode 100644 nla-common/src/main/java/cn/nla/common/model/OrderMessage.java create mode 100644 nla-order-service/src/main/java/cn/nla/order/config/RabbitMQConfig.java diff --git a/nla-common/src/main/java/cn/nla/common/model/OrderMessage.java b/nla-common/src/main/java/cn/nla/common/model/OrderMessage.java new file mode 100644 index 0000000..5382eb5 --- /dev/null +++ b/nla-common/src/main/java/cn/nla/common/model/OrderMessage.java @@ -0,0 +1,16 @@ +package cn.nla.common.model; + +import lombok.Data; + +@Data +public class OrderMessage { + /** + * 消息id + */ + private Long messageId; + /** + * 订单号 + */ + private String outTradeNo; + +} diff --git a/nla-order-service/src/main/java/cn/nla/order/config/RabbitMQConfig.java b/nla-order-service/src/main/java/cn/nla/order/config/RabbitMQConfig.java new file mode 100644 index 0000000..ad10a51 --- /dev/null +++ b/nla-order-service/src/main/java/cn/nla/order/config/RabbitMQConfig.java @@ -0,0 +1,103 @@ +package cn.nla.order.config; + +import lombok.Data; +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.Exchange; +import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.TopicExchange; +import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +@Data +public class RabbitMQConfig { + /** + * 交换机 + */ + @Value("${mq.config.order_event_exchange}") + private String eventExchange; + /** + * 延迟队列 + */ + @Value("${mq.config.order_close_delay_queue}") + private String orderCloseDelayQueue; + /** + * 关单队列 + */ + @Value("${mq.config.order_close_queue}") + private String orderCloseQueue; + /** + * 进入延迟队列的路由key + */ + @Value("${mq.config.order_close_delay_routing_key}") + private String orderCloseDelayRoutingKey; + /** + * 进入死信队列的路由key + */ + @Value("${mq.config.order_close_routing_key}") + private String orderCloseRoutingKey; + /** + * 过期时间 + */ + @Value("${mq.config.ttl}") + private Integer ttl; + + /** + * 消息转换器 + * @return + */ + @Bean + public MessageConverter messageConverter(){ + return new Jackson2JsonMessageConverter(); + } + /** + * 创建交换机 Topic类型,也可以用dirct路由 + * 一般一个微服务一个交换机 + * @return + */ + @Bean + public Exchange orderEventExchange(){ + return new TopicExchange(eventExchange,true,false); + } + /** + * 延迟队列 + */ + @Bean + public Queue orderCloseDelayQueue(){ + Map args = new HashMap<>(3); + args.put("x-dead-letter-exchange",eventExchange); + args.put("x-dead-letter-routing-key",orderCloseRoutingKey); + args.put("x-message-ttl",ttl); + return new Queue(orderCloseDelayQueue,true,false,false,args); + } + /** + * 死信队列,普通队列,用于被监听 + */ + @Bean + public Queue orderCloseQueue(){ + return new Queue(orderCloseQueue,true,false,false); + } + /** + * 第一个队列,即延迟队列的绑定关系建立 + * @return + */ + @Bean + public Binding orderCloseDelayBinding(){ + return new Binding(orderCloseDelayQueue,Binding.DestinationType.QUEUE,eventExchange,orderCloseDelayRoutingKey,null); + } + /** + * 死信队列绑定关系建立 + * @return + */ + @Bean + public Binding orderCloseBinding(){ + return new Binding(orderCloseQueue,Binding.DestinationType.QUEUE,eventExchange,orderCloseRoutingKey,null); + } + +} diff --git a/nla-order-service/src/main/java/cn/nla/order/mapper/ProductOrderItemMapper.java b/nla-order-service/src/main/java/cn/nla/order/mapper/ProductOrderItemMapper.java index 26204d3..f6355d3 100644 --- a/nla-order-service/src/main/java/cn/nla/order/mapper/ProductOrderItemMapper.java +++ b/nla-order-service/src/main/java/cn/nla/order/mapper/ProductOrderItemMapper.java @@ -2,6 +2,9 @@ package cn.nla.order.mapper; import cn.nla.order.model.entity.ProductOrderItemEntity; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** *

@@ -13,4 +16,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; */ public interface ProductOrderItemMapper extends BaseMapper { + /** + * 批量插入 + */ + void insertBatch( @Param("orderItemList") List list); } diff --git a/nla-order-service/src/main/java/cn/nla/order/model/entity/ProductOrderEntity.java b/nla-order-service/src/main/java/cn/nla/order/model/entity/ProductOrderEntity.java index d78dc6e..d948903 100644 --- a/nla-order-service/src/main/java/cn/nla/order/model/entity/ProductOrderEntity.java +++ b/nla-order-service/src/main/java/cn/nla/order/model/entity/ProductOrderEntity.java @@ -70,7 +70,7 @@ public class ProductOrderEntity implements Serializable { /** * 用户id */ - private Integer userId; + private Long userId; /** * 0表示未删除,1表示已经删除 diff --git a/nla-order-service/src/main/java/cn/nla/order/service/impl/ProductOrderServiceImpl.java b/nla-order-service/src/main/java/cn/nla/order/service/impl/ProductOrderServiceImpl.java index 8be405c..a13e157 100644 --- a/nla-order-service/src/main/java/cn/nla/order/service/impl/ProductOrderServiceImpl.java +++ b/nla-order-service/src/main/java/cn/nla/order/service/impl/ProductOrderServiceImpl.java @@ -1,31 +1,36 @@ package cn.nla.order.service.impl; import cn.nla.common.constant.CacheKey; -import cn.nla.common.enums.BizCodeEnum; -import cn.nla.common.enums.CouponStateEnum; +import cn.nla.common.enums.*; import cn.nla.common.exception.BizException; import cn.nla.common.interceptor.LoginInterceptor; import cn.nla.common.model.LoginUser; +import cn.nla.common.model.OrderMessage; import cn.nla.common.util.CommonUtil; import cn.nla.common.util.JsonData; +import cn.nla.order.config.RabbitMQConfig; import cn.nla.order.feign.CouponFeignService; import cn.nla.order.feign.ProductFeignService; import cn.nla.order.feign.UserFeignService; +import cn.nla.order.mapper.ProductOrderItemMapper; import cn.nla.order.model.VO.CouponRecordVO; import cn.nla.order.model.VO.OrderItemVO; import cn.nla.order.model.VO.ProductOrderAddressVO; import cn.nla.order.model.entity.ProductOrderEntity; import cn.nla.order.mapper.ProductOrderMapper; +import cn.nla.order.model.entity.ProductOrderItemEntity; import cn.nla.order.model.request.ConfirmOrderRequest; import cn.nla.order.model.request.LockCouponRecordRequest; import cn.nla.order.model.request.LockProductRequest; import cn.nla.order.model.request.OrderItemRequest; import cn.nla.order.service.ProductOrderService; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; @@ -34,6 +39,7 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.stream.Collectors; @@ -61,6 +67,15 @@ public class ProductOrderServiceImpl extends ServiceImpl orderItemList) { + List list = orderItemList.stream().map( + obj->{ + ProductOrderItemEntity itemDO = new ProductOrderItemEntity(); + itemDO.setBuyNum(obj.getBuyNum()); + itemDO.setProductId(obj.getProductId()); + itemDO.setProductImg(obj.getProductImg()); + itemDO.setProductName(obj.getProductTitle()); + itemDO.setOutTradeNo(orderOutTradeNo); + itemDO.setCreateTime(new Date()); + //单价 + itemDO.setAmount(obj.getAmount()); + //总价 + itemDO.setTotalAmount(obj.getTotalAmount()); + itemDO.setProductOrderId(orderId); + return itemDO; + } + ).collect(Collectors.toList()); + productOrderItemMapper.insertBatch(list); + } + + /** + * 创建订单 + */ + private ProductOrderEntity saveProductOrder(ConfirmOrderRequest orderRequest, LoginUser loginUser, String orderOutTradeNo, ProductOrderAddressVO addressVO) { + ProductOrderEntity productOrder = new ProductOrderEntity(); + productOrder.setUserId(loginUser.getId()); + productOrder.setHeadImg(loginUser.getHeadImg()); + productOrder.setNickname(loginUser.getName()); + productOrder.setOutTradeNo(orderOutTradeNo); + productOrder.setCreateTime(new Date()); + productOrder.setDel(0); + productOrder.setOrderType(ProductOrderTypeEnum.DAILY.name()); + //实际支付的价格 + productOrder.setPayAmount(orderRequest.getRealPayAmount()); + //总价,未使用优惠券的价格 + productOrder.setTotalAmount(orderRequest.getTotalAmount()); + productOrder.setState(ProductOrderStateEnum.NEW.name()); + productOrder.setPayType(ProductOrderPayTypeEnum.valueOf(orderRequest.getPayType()).name()); + productOrder.setReceiverAddress(JSON.toJSONString(addressVO)); + baseMapper.insert(productOrder); + return productOrder; + } + + /** * 锁定优惠券 */ @@ -158,12 +228,12 @@ public class ProductOrderServiceImpl extends ServiceImpl() + ProductOrderEntity productOrder = baseMapper.selectOne(new QueryWrapper() .eq("out_trade_no", outTradeNo)); - if (productOrderDO == null) { + if (productOrder == null) { return ""; } else { - return productOrderDO.getState(); + return productOrder.getState(); } } diff --git a/nla-order-service/src/main/resources/application.yml b/nla-order-service/src/main/resources/application.yml index 600812e..96650a0 100644 --- a/nla-order-service/src/main/resources/application.yml +++ b/nla-order-service/src/main/resources/application.yml @@ -21,6 +21,34 @@ spring: # username: nacos # password: sW5U%pxecL#p # namespace: yjs + #消息队列 + rabbitmq: + host: 192.168.30.130 + port: 5672 + virtual-host: / + password: admin + username: admin + #开启手动确认消息 + listener: + simple: + acknowledge-mode: manual + +##自定义消息队列配置,发送锁定库存消息-》延迟exchange-》lock.queue-》死信exchange-》release.queue +mq: + config: + #延迟队列,不能被监听消费 + order_close_delay_queue: stock.release.delay.queue + #延迟队列的消息过期后转发的队列 + order_close_queue: stock.release.queue + #交换机 + order_event_exchange: stock.event.exchange + #进入延迟队列的路由key + order_close_delay_routing_key: stock.release.delay.routing.key + #消息过期,进入释放队列的key + order_close_routing_key: stock.release.routing.key + #消息过期时间,毫秒,临时改为6分钟 + ttl: 60000 + #配置plus打印sql⽇志 mybatis-plus: configuration: diff --git a/nla-order-service/src/main/resources/mapper/ProductOrderItemMapper.xml b/nla-order-service/src/main/resources/mapper/ProductOrderItemMapper.xml index 4efeca3..cdeb0ee 100644 --- a/nla-order-service/src/main/resources/mapper/ProductOrderItemMapper.xml +++ b/nla-order-service/src/main/resources/mapper/ProductOrderItemMapper.xml @@ -4,21 +4,42 @@ - - - - - - - - - - + + + + + + + + + + - id, product_order_id, out_trade_no, product_id, product_name, product_img, buy_num, create_time, total_amount, amount + product_order_id, out_trade_no, product_id, product_name, product_img, buy_num, create_time, total_amount, amount + + + insert into product_order_item + ( + + ) + values + + ( + #{item.productOrderId}, + #{item.outTradeNo}, + #{item.productId}, + #{item.productName}, + #{item.productImg}, + #{item.buyNum}, + #{item.createTime}, + #{item.totalAmount}, + #{item.amount} + ) + +