up:: SpringBoot电商项目订单模块介绍
说明:
(1) 本篇博客的内容:开发【前台:创建订单】接口;
(2) 本篇博客的内容比较多,主要需要注意以下几点:
● 要明确【创建订单】的思路和流程;
● 为了实现同一个业务,具体的编码逻辑可能存在差异;但随着自己编程能力的提升、开发技巧的积累;应该能编写出越来越好的代码;
● 涉及到了枚举类的使用;
● Spring Boot手动控制事务;
● 关于本篇博客中的几个比较中的点,自己单独写了几篇附加博客,来说明,可以去参考;
一:【前提:创建订单】:分析;
1.【前台:创建订单】,在整个【订单模块】中的位置;
2.【前台:创建订单】,思路分析;
(1.1) 首先,【前台:创建订单】接口:入参说明;
(1.2) 所以,用户id数据、购物车中的商品数据,都需要我们自己去获取;
(2) 我们要判断,【当前用户的、购物车中已经被勾选的、将要被我们下单的,商品】是否存在,如果存在再看其是否还是上架状态;
(3) 还要判断,【当前用户的、购物车中已经被勾选的、将要被我们下单的,商品】是否库存足够,以防止超卖;(PS:如果,一切顺利,下单后,还要及时的扣库存)
(4) 用户下单时,首先,会删除【当前用户的、购物车中的、这个已经被勾选的、将要被下单的,商品】;也就是,删除cart表中,对应的记录;
(5) 然后,我们需要编写逻辑,生成一个订单号;
(6) 然后,会创建一个订单;也就是在order表中,新增一个订单记录;
(7) 然后,也要利用循环,把订单中的每种商品,写到order_item表中;
(8) 因为,【前台:创建订单】过程涉及多个数据库的写操作,所以我们这儿需要手动控制数据库事务;
至于,数据库事务,在【附加SpringBoot项目手动控制事务包括总结了到目前为止事务的所有内容】中,我们再次做了总结,如有需要可以去查看;
二:正式开发;
1.创建【订单模块】对应的OrderController;编写前台创建订单的方法:createOrder()方法;
说明:
(1)请求方式,url要符合接口文档要求;
● 有关@RequestBody注解,如有需要可以参考【附加POST请求方法参数放在url中和放在body中有什么区别】;
(2)因为,这个接口有三个参数,虽然不是很多,我们还是创建了一个实体类CreateOrderReq,来帮助承接参数;
● 同时,上面使用了@Valid注解,进行了Validation参数校验;
(3)使用实体类CreateOrderReq,去承接参数;并开启了Valid参数校验;
(4)Service层创建订单的逻辑方法create()方法,在下一部分介绍;
2.创建OrderService接口,OrderServiceImpl实现类;
3.在OrderServiceImpl实现类编写创建订单的逻辑方法:create()方法;
说明:
(1)通过UserFilter获取当前登录用户;
(2)然后,调用【cartService.list(userId);】去查询【当前用户的、购物车中的、商品状态仍然是上架状态的】所有商品数据;
● 这个方法,是在开发购物车模块的【购物车列表】接口时开发的,其作用是:查询【当前用户的、购物车中的、商品状态仍然是上架状态的】购物车信息;
● 如有需要,可以快速参考【SpringBoot电商项目购物车模块购物车列表接口】;
● 只是需要注意,这个方法的返回结果CartVO是经过处理、组合的,其中属性还是比较丰富的;
(3)然后,筛选出,当前购物车中,那些被勾选的商品;
(4)如果【购物车中,validSaleStatusAndStock没有被勾选的商品】,就抛出一个异常;
(5)编写一个工具方法validSaleStatusAndStock(),去检查,这些被勾选的商品:是否还存在、是否是上架状态、库存是否足够;
(PS:其实,但就这儿的情况来说,上面(2)中的方法,查出来的就已经是:商品存在、商品是上架状态的了;所以,但就这儿的情况来说,validSaleStatusAndStock()方法做了点重复工作)
(6)然后,因为我们在创建订单的时候,需要把订单中商品的信息,存储到order_item表中;所以,我们编写方法,通过CartVO,来构建OrderItem;
(7)扣库存;
(8)然后,删除【当前用户的、购物车中的、商品是上架状态的、库存足够的、被勾选的】那些商品;
很自然,当我们把购物车中某些商品下单后,这些商品是应该从购物车中删除的;
PS:这儿需要明确的时,我们在下单的过程中,任何地方不符合要求,都会抛出异常;如果能一步一步走到这儿,就说明前面是符合要求的;
(9)然后,编写OrderCodeFactory工具类,去生成订单号;
(10.1)创建一个订单Order对象,并将其添加到order表中;
(10.2)其中,使用了枚举类,来管理“订单状态”信息;
● 在本项目中,多次使用了枚举;可以参考【SpringBoot电商项目用户模块枚举类和枚举数据类型】,【SpringBoot电商项目用户模块API统一返回对象】;
● 至于,为什么我们这儿又使用枚举类来定义常量,而不使用内部接口定义常量了;
可以看下,这个回答;(PS:虽然,有点点文不对题,不太能解决自己的疑惑,,,但其内容,还是很有参考价值的)
● 这儿,为了能够通过code,获得对应的value信息,我们编写了codeOf()方法;
(10.3)给剩余的属性赋值,然后插入到order表中;
(11)利用循环,把订单中的每种商品,写到order_item表中;
4.在OrderService接口中,反向生成方法的声明;
5.添加数据库事务;
● 很显然,创建订单的时候,这一个业务逻辑,底层需要多次的增删改操作;所以,我们需要去手动控制事务;
● 有关,事务及Spring Boot中使用事务,可以参考【附加SpringBoot项目手动控制事务包括总结了到目前为止事务的所有内容】;
通过【@Transactional(rollbackFor = Exception.class)】来设置手动控制事务;
三:测试;
可以看到,该用户的购物车中被勾选的商品,已经被删除了;