说明:
(1)本篇博客的内容:开发【前台:创建订单】接口;
(2)本篇博客的内容比较多,主要需要注意以下几点:
● 要明确【创建订单】的思路和流程;
● 为了实现同一个业务,具体的编码逻辑可能存在差异;但随着自己编程能力的提升、开发技巧的积累;应该能编写出越来越好的代码;
● 涉及到了枚举类的使用;
● Spring Boot手动控制事务;
● 关于本篇博客中的几个比较中的点,自己单独写了几篇附加博客,来说明,可以去参考;
目录
1.创建【订单模块】对应的OrderController;编写前台创建订单的方法:createOrder()方法;
(2)因为,这个接口有三个参数,虽然不是很多,我们还是创建了一个实体类CreateOrderReq,来帮助承接参数;
(3)使用实体类CreateOrderReq,去承接参数;并开启了Valid参数校验;
(4)Service层创建订单的逻辑方法create()方法,在下一部分介绍;
2.创建OrderService接口,OrderServiceImpl实现类;
3.在OrderServiceImpl实现类编写创建订单的逻辑方法:create()方法;
(2)然后,调用【cartService.list(userId);】去查询【当前用户的、购物车中的、商品状态仍然是上架状态的】所有商品数据;
(4)如果【购物车中,validSaleStatusAndStock没有被勾选的商品】,就抛出一个异常;
(5)编写一个工具方法validSaleStatusAndStock(),去检查,这些被勾选的商品:是否还存在、是否是上架状态、库存是否足够;
(6)然后,因为我们在创建订单的时候,需要把订单中商品的信息,存储到order_item表中;所以,我们编写方法,通过CartVO,来构建OrderItem;
(8)然后,删除【当前用户的、购物车中的、商品是上架状态的、库存足够的、被勾选的】那些商品;
(9)然后,编写OrderCodeFactory工具类,去生成订单号;
(10.1)创建一个订单Order对象,并将其添加到order表中;
(11)利用循环,把订单中的每种商品,写到order_item表中;
一:【前提:创建订单】:分析;
1.【前台:创建订单】,在整个【订单模块】中的位置;
2.【前台:创建订单】,思路分析;
(1.1)首先,【前台:创建订单】接口:入参说明;
(1.2)所以,用户id数据、购物车中的商品数据,都需要我们自己去获取;
(2)我们要判断,【当前用户的、购物车中已经被勾选的、将要被我们下单的,商品】是否存在,如果存在再看其是否还是上架状态;
(3)还要判断,【当前用户的、购物车中已经被勾选的、将要被我们下单的,商品】是否库存足够,以防止超卖;(PS:如果,一切顺利,下单后,还要及时的扣库存)
(4)用户下单时,首先,会删除【当前用户的、购物车中的、这个已经被勾选的、将要被下单的,商品】;也就是,删除cart表中,对应的记录;
(5)然后,我们需要编写逻辑,生成一个订单号;
(6)然后,会创建一个订单;也就是在order表中,新增一个订单记录;
(7)然后,也要利用循环,把订单中的每种商品,写到order_item表中;
(8)因为,【前台:创建订单】过程涉及多个数据库的写操作,所以我们这儿需要手动控制数据库事务;
至于,数据库事务,在【附加:Spring Boot项目,手动控制事务;(包括:总结了到目前为止,事务的所有内容;)】中,我们再次做了总结,如有需要可以去查看;
二:正式开发;
1.创建【订单模块】对应的OrderController;编写前台创建订单的方法:createOrder()方法;
package com.imooc.mall.controller; import com.imooc.mall.common.ApiRestResponse; import com.imooc.mall.model.request.CreateOrderReq; import com.imooc.mall.service.OrderService; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; /** * 描述:订单Controller */ @RestController public class OrderController { @Autowired OrderService orderService; /** * 【前台:创建订单】接口; * @param createOrderReq * @return */ @ApiOperation("创建订单") @PostMapping("/order/create ") public ApiRestResponse createOrder(@Valid @RequestBody CreateOrderReq createOrderReq) { String orderNum = orderService.create(createOrderReq); return ApiRestResponse.success(orderNum); } }
说明:
(1)请求方式,url要符合接口文档要求;
● 有关@RequestBody注解,如有需要可以参考【附加:【POST请求:方法参数放在url中和放在body中,有什么区别】;也包括【@Param,@RequestParam,@RequestBody这三个【与接收参数有关】的注解,总结】;】;
……………………………………………………
(2)因为,这个接口有三个参数,虽然不是很多,我们还是创建了一个实体类CreateOrderReq,来帮助承接参数;
● 同时,上面使用了@Valid注解,进行了Validation参数校验;
……………………………………………………
(3)使用实体类CreateOrderReq,去承接参数;并开启了Valid参数校验;
……………………………………………………
(4)Service层创建订单的逻辑方法create()方法,在下一部分介绍;
2.创建OrderService接口,OrderServiceImpl实现类;