Browse Source

feat: 更新业务逻辑

master
xc-yjs 7 months ago
parent
commit
0d7648b8cc
  1. 16
      nla-common/src/main/java/cn/nla/common/model/OrderMessage.java
  2. 103
      nla-order-service/src/main/java/cn/nla/order/config/RabbitMQConfig.java
  3. 7
      nla-order-service/src/main/java/cn/nla/order/mapper/ProductOrderItemMapper.java
  4. 2
      nla-order-service/src/main/java/cn/nla/order/model/entity/ProductOrderEntity.java
  5. 84
      nla-order-service/src/main/java/cn/nla/order/service/impl/ProductOrderServiceImpl.java
  6. 28
      nla-order-service/src/main/resources/application.yml
  7. 43
      nla-order-service/src/main/resources/mapper/ProductOrderItemMapper.xml

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

103
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<String,Object> 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);
}
}

7
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;
/**
* <p>
@ -13,4 +16,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface ProductOrderItemMapper extends BaseMapper<ProductOrderItemEntity> {
/**
* 批量插入
*/
void insertBatch( @Param("orderItemList") List<ProductOrderItemEntity> list);
}

2
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表示已经删除

84
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<ProductOrderMapper, Pro
@Resource
private ProductFeignService productFeignService;
@Resource
private ProductOrderItemMapper productOrderItemMapper;
@Resource
private RabbitTemplate rabbitTemplate;
@Resource
private RabbitMQConfig rabbitMQConfig;
@Override
public JsonData confirmOrder(ConfirmOrderRequest request) {
LoginUser loginUser = LoginInterceptor.threadLocal.get();
@ -97,13 +112,68 @@ public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, Pro
this.lockCouponRecords(request, orderOutTradeNo);
//锁定库存
this.lockProductStocks(orderItemList, orderOutTradeNo);
// //创建订单
// ProductOrderDO productOrderDO = this.saveProductOrder(request, loginUser, orderOutTradeNo, addressVO);
//创建订单
ProductOrderEntity productOrder = this.saveProductOrder(request,loginUser,orderOutTradeNo,addressVO);
//创建订单项
this.saveProductOrderItems(orderOutTradeNo,productOrder.getId(),orderItemList);
//发送延迟消息,用于自动关单
OrderMessage orderMessage = new OrderMessage();
orderMessage.setOutTradeNo(orderOutTradeNo);
rabbitTemplate.convertAndSend(rabbitMQConfig.getEventExchange(),rabbitMQConfig.getOrderCloseDelayRoutingKey(),orderMessage);
return null;
}
/**
* 新增订单项
*/
private void saveProductOrderItems(String orderOutTradeNo, Long orderId, List<OrderItemVO> orderItemList) {
List<ProductOrderItemEntity> 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<ProductOrderMapper, Pro
@Override
public String queryProductOrderState(String outTradeNo) {
ProductOrderEntity productOrderDO = baseMapper.selectOne(new QueryWrapper<ProductOrderEntity>()
ProductOrderEntity productOrder = baseMapper.selectOne(new QueryWrapper<ProductOrderEntity>()
.eq("out_trade_no", outTradeNo));
if (productOrderDO == null) {
if (productOrder == null) {
return "";
} else {
return productOrderDO.getState();
return productOrder.getState();
}
}

28
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:

43
nla-order-service/src/main/resources/mapper/ProductOrderItemMapper.xml

@ -4,21 +4,42 @@
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.nla.order.model.entity.ProductOrderItemEntity">
<id column="id" property="id" />
<result column="product_order_id" property="productOrderId" />
<result column="out_trade_no" property="outTradeNo" />
<result column="product_id" property="productId" />
<result column="product_name" property="productName" />
<result column="product_img" property="productImg" />
<result column="buy_num" property="buyNum" />
<result column="create_time" property="createTime" />
<result column="total_amount" property="totalAmount" />
<result column="amount" property="amount" />
<id column="id" property="id"/>
<result column="product_order_id" property="productOrderId"/>
<result column="out_trade_no" property="outTradeNo"/>
<result column="product_id" property="productId"/>
<result column="product_name" property="productName"/>
<result column="product_img" property="productImg"/>
<result column="buy_num" property="buyNum"/>
<result column="create_time" property="createTime"/>
<result column="total_amount" property="totalAmount"/>
<result column="amount" property="amount"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
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
</sql>
<!--批量插入-->
<insert id="insertBatch">
insert into product_order_item
(
<include refid="Base_Column_List"/>
)
values
<foreach collection="orderItemList" item="item" index="index" separator=",">
(
#{item.productOrderId},
#{item.outTradeNo},
#{item.productId},
#{item.productName},
#{item.productImg},
#{item.buyNum},
#{item.createTime},
#{item.totalAmount},
#{item.amount}
)
</foreach>
</insert>
</mapper>

Loading…
Cancel
Save