锁定商品库存及优惠券记录

This commit is contained in:
jieyuu 2024-09-22 20:48:30 +08:00
parent 9e04504740
commit 290eea787e
8 changed files with 166 additions and 7 deletions

View File

@ -1,18 +1,31 @@
package net.jieyuu.feign;
import io.swagger.annotations.ApiParam;
import net.jieyuu.request.LockCouponRecordRequest;
import net.jieyuu.utils.JsonData;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = "xdclass-coupon-service")
public interface CouponFeignService {
/**
* 查询用户的优惠券是否可用注意防止水平越权
*
* @param recordId
* @return
*/
@GetMapping("/api/coupon_record/v1/detail/{record_id}")
JsonData findUserCouponRecordById(@PathVariable("record_id") long recordId);
/**
* 锁定优惠券
*
* @param lockCouponRecordRequest
* @return
*/
@PostMapping("/api/coupon_record/v1/lock_records")
JsonData lockCouponRecords(@ApiParam("锁定优惠券请求对象") @RequestBody LockCouponRecordRequest lockCouponRecordRequest);
}

View File

@ -1,8 +1,12 @@
package net.jieyuu.feign;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import net.jieyuu.request.LockProductRequest;
import net.jieyuu.utils.JsonData;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@ -19,4 +23,13 @@ public interface ProductFeignService {
@PostMapping("/api/cart/v1/confirm_order_cart_items")
public JsonData confirmOrderCartItems(@RequestBody List<Long> productIdList);
/**
* 锁定商品购物项库存
*
* @param lockProductRequest
* @return
*/
@PostMapping("/api/product/v1/lock_products")
public JsonData lockProductStocks(@RequestBody LockProductRequest lockProductRequest);
}

View File

@ -0,0 +1,26 @@
package net.jieyuu.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ApiModel(value = "优惠券锁定对象", description = "优惠券锁定对象")
@Data
public class LockCouponRecordRequest {
/**
* 优惠券记录id列表
*/
@ApiModelProperty(value = "优惠券锁定数组", example = "[1,2,3]")
private List<Long> lockCouponRecordIds;
/**
* 订单号
*/
@ApiModelProperty(value = "订单号", example = "32位uuid")
private String orderOutTradeNo;
}

View File

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

View File

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

View File

@ -15,6 +15,9 @@ import net.jieyuu.model.OrderItemVO;
import net.jieyuu.model.ProductOrderDO;
import net.jieyuu.mapper.ProductOrderMapper;
import net.jieyuu.request.ConfirmOrderRequest;
import net.jieyuu.request.LockCouponRecordRequest;
import net.jieyuu.request.LockProductRequest;
import net.jieyuu.request.OrderItemRequest;
import net.jieyuu.service.ProductOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.jieyuu.utils.CommonUtil;
@ -25,7 +28,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
@ -89,10 +94,70 @@ public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, Pro
}
// 验证价格
this.checkPrice(orderItemList, orderRequest);
// 锁定优惠券
this.lockCouponRecords(orderRequest, orderOutTradeNo);
// 锁定库存
this.lockProductStocks(orderItemList, orderOutTradeNo);
// 创建订单 todo
//创建支付 todo
return null;
}
/**
* 锁定商品库存
*
* @param orderItemList
* @param orderOutTradeNo
*/
private void lockProductStocks(List<OrderItemVO> orderItemList, String orderOutTradeNo) {
List<OrderItemRequest> itemRequestLis = orderItemList.stream().map(obj -> {
OrderItemRequest request = new OrderItemRequest();
request.setBuyNum(obj.getBuyNum());
request.setProductId(obj.getProductId());
return request;
}).collect(Collectors.toList());
LockProductRequest lockProductRequest = new LockProductRequest();
lockProductRequest.setOrderItemList(itemRequestLis);
lockProductRequest.setOrderOutTradeNo(orderOutTradeNo);
JsonData jsonData = productFeignService.lockProductStocks(lockProductRequest);
if (jsonData.getCode() != 0) {
log.error("锁定商品库存失败:{}", lockProductRequest);
throw new BizException(BizCodeEnum.ORDER_CONFIRM_LOCK_PRODUCT_FAIL);
}
}
/**
* 锁定优惠券记录
* 可以使用异步的方式
*
* @param orderOutTradeNo
* @param orderRequest
*/
private void lockCouponRecords(ConfirmOrderRequest orderRequest, String orderOutTradeNo) {
List<Long> lockCouponRecordIds = new ArrayList<>();
if (orderRequest.getCouponRecordId() > 0) {
lockCouponRecordIds.add(orderRequest.getCouponRecordId());
LockCouponRecordRequest lockCouponRecordRequest = new LockCouponRecordRequest();
lockCouponRecordRequest.setLockCouponRecordIds(lockCouponRecordIds);
lockCouponRecordRequest.setOrderOutTradeNo(orderOutTradeNo);
// 发送优惠券请求
JsonData jsonData = couponFeignService.lockCouponRecords(lockCouponRecordRequest);
if (jsonData.getCode() != 0) {
throw new BizException(BizCodeEnum.COUPON_RECORD_LOCK_FAIL);
}
}
}
/**
* 验证价格
* 1)统计所有商品价格
@ -124,14 +189,14 @@ public class ProductOrderServiceImpl extends ServiceImpl<ProductOrderMapper, Pro
if (couponRecordVO.getPrice().compareTo(realPayAmount) > 0) { // 防止出现优惠券抵扣超过商品价格
realPayAmount = BigDecimal.ZERO;
}else{
realPayAmount= realPayAmount.subtract(couponRecordVO.getPrice());
} else {
realPayAmount = realPayAmount.subtract(couponRecordVO.getPrice());
}
}
// 验价
if(realPayAmount.compareTo(orderRequest.getTotalAmount())!=0){
log.error("订单验价失败:{}" , orderRequest);
if (realPayAmount.compareTo(orderRequest.getTotalAmount()) != 0) {
log.error("订单验价失败:{}", orderRequest);
throw new BizException(BizCodeEnum.ORDER_CONFIRM_PRICE_FAIL);
}
}

View File

@ -66,7 +66,7 @@ public class ProductController {
* @return
*/
@ApiOperation("商品库存锁定")
@PutMapping("lock_products")
@PostMapping("lock_products")
public JsonData lockProduct(@ApiParam("商品库存锁定") @RequestBody LockProductRequest lockProductRequest) {
JsonData jsonData = productService.lockProductStock(lockProductRequest);
return jsonData;

View File

@ -18,7 +18,5 @@ public class LockProductRequest {
@ApiModelProperty(value = "订单项")
@JsonProperty("order_item_list")
private List<OrderItemRequest> orderItemList;
}