乐优商城(四十四)订单中心重构

目录

一、目录结构

二、修改创建订单方法

2.1 Controller

2.2 库存检查

2.3 创建订单

三、前端修改


秒杀系统要调用订单微服务中的下订单功能,所以将原来的订单微服务进行重构。

一、目录结构

将原来的pojo抽取到interface中,并且增加orderApi接口:

package com.leyou.order.api;

import com.leyou.order.pojo.Order;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * @Author: 98050
 * @Time: 2018-11-12 15:13
 * @Feature: 订单服务接口
 */
@RequestMapping("order")
public interface OrderApi {

    /**
     * 创建订单
     * @param seck
     * @param order
     * @return
     */
    @PostMapping
    ResponseEntity<List<Long>> createOrder(@RequestParam("seck") String seck, @RequestBody @Valid Order order);
}

二、修改创建订单方法

要判断是普通订单还是秒杀订单,通过传入的seck来判断,还有就是以前的方法没有修改库存。。。。。。。。。。。。。。。。。。。。

2.1 Controller

    /**
     * 创建订单
     * @param order 订单对象
     * @return 订单编号
     */
    @PostMapping
    @ApiOperation(value = "创建订单接口,返回订单编号",notes = "创建订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "order",required = true,value = "订单的json对象,包含订单条目和物流信息"),
            @ApiImplicitParam(name = "tag",required = true,value = "是否是秒杀订单")
    })
    public ResponseEntity<List<Long>> createOrder(@RequestParam("seck") String seck,@RequestBody @Valid Order order){
        System.out.println(seck);
        List<Long> skuId = this.orderService.queryStock(seck,order);
        if (skuId != null && skuId.size() != 0){
            //库存不足
            return new ResponseEntity<>(skuId,HttpStatus.OK);
        }

        Long id = this.orderService.createOrder(seck,order);
        return new ResponseEntity<>(Arrays.asList(id), HttpStatus.CREATED);
    }

2.2 库存检查

在下订单前先对订单中的商品库存进行检验,如果库存余量不足,那么就直接返回对应的商品id。

orderService中添加方法queryStock:

    /**
     * 查询订单下商品的库存,返回库存不足的商品Id
     * @param order
     * @return
     */
    @Override
    public List<Long> queryStock(String tag,Order order) {
        String seck = "seckill";
        List<Long> skuId = new ArrayList<>();
        order.getOrderDetails().forEach(orderDetail -> {
            Stock stock = this.stockMapper.selectByPrimaryKey(orderDetail.getSkuId());
            if (stock.getStock() - orderDetail.getNum() < 0){
                //先判断库存是否充足
                skuId.add(orderDetail.getSkuId());
            }else{
                //充足的话就判断秒杀库存是否充足
                if (StringUtils.isNotEmpty(tag) && seck.equals(tag)){
                    //检查秒杀库存
                    if (stock.getSeckillStock() - orderDetail.getNum() < 0){
                        skuId.add(orderDetail.getSkuId());
                    }
                }
            }
        });
        return skuId;
    }

2.3 创建订单

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createOrder(String tag,Order order) {

        //1.生成orderId
        long orderId = idWorker.nextId();
        //2.获取登录的用户
        UserInfo userInfo = LoginInterceptor.getLoginUser();
        //3.初始化数据
        order.setBuyerNick(userInfo.getUsername());
        order.setBuyerRate(false);
        order.setCreateTime(new Date());
        order.setOrderId(orderId);
        order.setUserId(userInfo.getId());
        //4.保存数据
        this.orderMapper.insertSelective(order);

        //5.保存订单状态
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setCreateTime(order.getCreateTime());
        //初始状态未未付款:1
        orderStatus.setStatus(1);
        //6.保存数据
        this.orderStatusMapper.insertSelective(orderStatus);

        //7.在订单详情中添加orderId
        order.getOrderDetails().forEach(orderDetail ->{
            //添加订单
            orderDetail.setOrderId(orderId);

        });
        //8.保存订单详情,使用批量插入功能
        this.orderDetailMapper.insertList(order.getOrderDetails());

        //9.更新库存
        order.getOrderDetails().forEach(orderDetail -> this.stockMapper.reduceStock(orderDetail.getSkuId(),orderDetail.getNum()));

        //10.如果是秒杀订单,那么修改秒杀商品库存
        String seck = "seckill";
        if (StringUtils.isNotEmpty(tag) && tag.equals(seck)){
            order.getOrderDetails().forEach(orderDetail -> this.stockMapper.reduceSeckStock(orderDetail.getSkuId(),orderDetail.getNum()));
        }


        logger.debug("生成订单,订单编号:{},用户id:{}", orderId, userInfo.getId());
        return orderId;
    }

在stockMapper中增加方法reduceStock和rdeuceSeckStock:

库存stock一定要大于0,不能为负。

package com.leyou.order.mapper;

import com.leyou.item.pojo.Stock;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import tk.mybatis.mapper.common.Mapper;

/**
 * @Author: 98050
 * @Time: 2018-11-10 17:58
 * @Feature:
 */
public interface StockMapper extends Mapper<Stock> {


    /**
     * 更新对应商品的库存,且库存必须大于0,否则回滚。
     * @param skuId
     * @param num
     */
    @Update("update tb_stock set stock = stock - #{num} where sku_id = #{skuId} and stock > 0")
    void reduceStock(@Param("skuId") Long skuId, @Param("num") Integer num);

    /**
     * 更新对应商品的秒杀库存,且库存必须大于0,否则回滚。
     * @param skuId
     * @param num
     */
    @Update("update tb_stock set seckill_stock = seckill_stock - #{num} where sku_id = #{skuId} and seckill_stock > 0")
    void reduceSeckStock(@Param("skuId")Long skuId, @Param("num")Integer num);
}

三、前端修改

修改getOrderInfo.html页面中的订单提交方法:

根据返回的状态码来判断库存是否充足。返回数据是一个列表,所以就不用修改回调(避免long类型数据异常)。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值