商品库存锁定接口开发
This commit is contained in:
parent
4339d4de03
commit
90a8f1d1fc
@ -1,7 +1,6 @@
|
||||
package net.jieyuu.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.sun.org.apache.bcel.internal.generic.RETURN;
|
||||
import net.jieyuu.model.ProductOrderDO;
|
||||
import net.jieyuu.mapper.ProductOrderMapper;
|
||||
import net.jieyuu.service.ProductOrderService;
|
||||
|
@ -16,7 +16,7 @@ public class InterceptorConfig implements WebMvcConfigurer {
|
||||
registry
|
||||
.addInterceptor(new LoginInterceptor())
|
||||
//拦截的路径
|
||||
.addPathPatterns("/api/cart/*/**")
|
||||
.addPathPatterns("/api/product/*/lock_products", "/api/cart/*/**")
|
||||
//放行的路径
|
||||
.excludePathPatterns("");
|
||||
|
||||
|
@ -4,6 +4,7 @@ package net.jieyuu.controller;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import net.jieyuu.request.LockProductRequest;
|
||||
import net.jieyuu.service.ProductService;
|
||||
import net.jieyuu.utils.JsonData;
|
||||
import net.jieyuu.vo.ProductVO;
|
||||
@ -46,5 +47,18 @@ public class ProductController {
|
||||
return JsonData.buildSuccess(productVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 商品库存锁定
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation("商品库存锁定")
|
||||
@PutMapping("lock_products")
|
||||
public JsonData lockProduct(@ApiParam("商品库存锁定") @RequestBody LockProductRequest lockProductRequest) {
|
||||
JsonData jsonData = productService.lockProductStock(lockProductRequest);
|
||||
return jsonData;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package net.jieyuu.mapper;
|
||||
|
||||
import net.jieyuu.model.ProductDO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -13,4 +14,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
*/
|
||||
public interface ProductMapper extends BaseMapper<ProductDO> {
|
||||
|
||||
/**
|
||||
* 锁定商品库存
|
||||
*
|
||||
* @param productId
|
||||
* @param buyNum
|
||||
* @return
|
||||
*/
|
||||
int lockProductStock(@Param("productId") long productId, @Param("buyNum") int buyNum);
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package net.jieyuu.request;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel(value = "商品锁定对象", description = "商品锁定对象协议")
|
||||
@Data
|
||||
public class LockProductRequest {
|
||||
|
||||
|
||||
@ApiModelProperty(value = "订单id", example = "1233332131231321")
|
||||
@JsonProperty("order_out_trade_no")
|
||||
private String orderOutTradeNo;
|
||||
|
||||
@ApiModelProperty(value = "订单项")
|
||||
@JsonProperty("order_item_list")
|
||||
private List<OrderItemRequest> orderItemList;
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package net.jieyuu.request;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel("商品子项")
|
||||
@Data
|
||||
public class OrderItemRequest {
|
||||
|
||||
@ApiModelProperty(value = "商品id",example = "1")
|
||||
@JsonProperty("product_id")
|
||||
private long productId;
|
||||
|
||||
@ApiModelProperty(value = "购买数量",example = "1")
|
||||
@JsonProperty("buy_num")
|
||||
private int buyNum;
|
||||
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
package net.jieyuu.service;
|
||||
|
||||
import net.jieyuu.model.ProductDO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import net.jieyuu.request.LockProductRequest;
|
||||
import net.jieyuu.utils.JsonData;
|
||||
import net.jieyuu.vo.ProductVO;
|
||||
|
||||
import java.util.List;
|
||||
@ -41,4 +42,12 @@ public interface ProductService {
|
||||
* @return
|
||||
*/
|
||||
List<ProductVO> findProductByIdBatch(List<Long> productIdList);
|
||||
|
||||
/**
|
||||
* 锁定商品库存
|
||||
*
|
||||
* @param lockProductRequest
|
||||
* @return
|
||||
*/
|
||||
JsonData lockProductStock(LockProductRequest lockProductRequest);
|
||||
}
|
||||
|
@ -4,10 +4,18 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.jieyuu.enums.BizCodeEnum;
|
||||
import net.jieyuu.enums.StockTaskStateEnum;
|
||||
import net.jieyuu.exception.BizException;
|
||||
import net.jieyuu.mapper.ProductTaskMapper;
|
||||
import net.jieyuu.model.ProductDO;
|
||||
import net.jieyuu.mapper.ProductMapper;
|
||||
import net.jieyuu.model.ProductTaskDO;
|
||||
import net.jieyuu.request.LockProductRequest;
|
||||
import net.jieyuu.request.OrderItemRequest;
|
||||
import net.jieyuu.service.ProductService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import net.jieyuu.utils.JsonData;
|
||||
import net.jieyuu.vo.ProductVO;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -16,6 +24,7 @@ import org.springframework.stereotype.Service;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -33,6 +42,16 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO> im
|
||||
@Autowired
|
||||
private ProductMapper productMapper;
|
||||
|
||||
@Autowired
|
||||
private ProductTaskMapper productTaskMapper;
|
||||
|
||||
/**
|
||||
* 分页查询商品列表
|
||||
*
|
||||
* @param page
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> page(int page, int size) {
|
||||
Page<ProductDO> pageInfo = new Page<>(page, size);
|
||||
@ -47,6 +66,12 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO> im
|
||||
return pageMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id找商品详情
|
||||
*
|
||||
* @param productId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ProductVO findDetailById(long productId) {
|
||||
ProductDO productDO = productMapper.selectById(productId);
|
||||
@ -54,6 +79,12 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO> im
|
||||
return beanProcess(productDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量查询
|
||||
*
|
||||
* @param productIdList
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<ProductVO> findProductByIdBatch(List<Long> productIdList) {
|
||||
List<ProductDO> productDOList = productMapper.selectList(new QueryWrapper<ProductDO>().in("id", productIdList));
|
||||
@ -61,6 +92,59 @@ public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO> im
|
||||
return productVOList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁定商品库存
|
||||
* 1)遍历商品,锁定每个商品购买数量
|
||||
* 2)每一次锁定的时候,都要发送延迟消息
|
||||
*
|
||||
* @param lockProductRequest
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public JsonData lockProductStock(LockProductRequest lockProductRequest) {
|
||||
|
||||
String outTradeNo = lockProductRequest.getOrderOutTradeNo();
|
||||
List<OrderItemRequest> orderItemList = lockProductRequest.getOrderItemList();
|
||||
|
||||
// 批量查询itemList的商品情况,减少连接
|
||||
// 提取itemList里面的所有id
|
||||
List<Long> productIdList = orderItemList.stream().map(OrderItemRequest::getProductId).collect(Collectors.toList());
|
||||
|
||||
//一次查询,结果分组
|
||||
//批量查询商品最新数据
|
||||
List<ProductVO> productVOList = this.findProductByIdBatch(productIdList);
|
||||
//根据id进行分组
|
||||
Map<Long, ProductVO> productMaps = productVOList.stream().collect(Collectors.toMap(ProductVO::getId, Function.identity()));
|
||||
|
||||
for (OrderItemRequest item : orderItemList) {
|
||||
|
||||
// 锁定商品记录
|
||||
int rows = productMapper.lockProductStock(item.getProductId(), item.getBuyNum());
|
||||
|
||||
if (rows != 1) {
|
||||
throw new BizException(BizCodeEnum.ORDER_CONFIRM_LOCK_PRODUCT_FAIL);
|
||||
} else {
|
||||
// 插入product_task
|
||||
ProductVO productVO = productMaps.get(item.getProductId());
|
||||
ProductTaskDO productTaskDO = new ProductTaskDO();
|
||||
productTaskDO.setBuyNum(item.getBuyNum());
|
||||
productTaskDO.setLockState(StockTaskStateEnum.LOCK.name());
|
||||
productTaskDO.setProductId(item.getProductId());
|
||||
productTaskDO.setOutTradeNo(outTradeNo);
|
||||
|
||||
// 假若不需要插入商品名,那么前文批量查询就不需要了
|
||||
// 此处为冗余字段
|
||||
productTaskDO.setProductName(productVO.getTitle());
|
||||
|
||||
// 插入product_task
|
||||
productTaskMapper.insert(productTaskDO);
|
||||
|
||||
// 发送MQ延迟消息, 延迟解锁商品库存 todo
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ProductVO beanProcess(ProductDO obj) {
|
||||
ProductVO productVO = new ProductVO();
|
||||
BeanUtils.copyProperties(obj, productVO);
|
||||
|
@ -4,20 +4,30 @@
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="net.jieyuu.model.ProductDO">
|
||||
<id column="id" property="id" />
|
||||
<result column="title" property="title" />
|
||||
<result column="cover_img" property="coverImg" />
|
||||
<result column="detail" property="detail" />
|
||||
<result column="old_amount" property="oldAmount" />
|
||||
<result column="amount" property="amount" />
|
||||
<result column="stock" property="stock" />
|
||||
<result column="create_time" property="createTime" />
|
||||
<result column="lock_stock" property="lockStock" />
|
||||
<id column="id" property="id"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="cover_img" property="coverImg"/>
|
||||
<result column="detail" property="detail"/>
|
||||
<result column="old_amount" property="oldAmount"/>
|
||||
<result column="amount" property="amount"/>
|
||||
<result column="stock" property="stock"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="lock_stock" property="lockStock"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, title, cover_img, detail, old_amount, amount, stock, create_time, lock_stock
|
||||
id
|
||||
, title, cover_img, detail, old_amount, amount, stock, create_time, lock_stock
|
||||
</sql>
|
||||
|
||||
<!--锁定商品库存-->
|
||||
<update id="lockProductStock">
|
||||
update product
|
||||
set lock_stock = lock_stock + #{buyNum}
|
||||
where id = #{productId}
|
||||
and stock - lock_stock >={buyNum}
|
||||
</update>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
Loading…
Reference in New Issue
Block a user