说明:
(1)本篇博客内容:开发【添加商品到购物车】接口;
(2)本篇博客需要注意的点:
● 如果接口返回的数据格式不符合接口的要求(接口要求返回JSON格式,而接口没有做相应的设置),也是会报404错误的;
● 一些复杂的、可以单独拉出来的逻辑,可以单独写一个方法;(以防止单个方法规模过于庞大)
● 对于,比如【不同的数字代表不同的含义】的地方,我们最好在Constant这个盛放常量的类中,予以说明;以防程序后来的维护者、接盘者,一时不知不同的数据到底代表什么含义;
(3)本篇博客出于安全考虑:而采用的一种广泛采用的做法:接口不能传入用户id,而是要在程序内部获取;否则,如果接口参数中有用户id的话,这很可能会被黑客利用,黑客就可以通过这个接口,给任何人的购物车中随意添加商品了;
其实,由此,也能感受到【接口的设计能力】,这个能力也是需要慢慢锻炼的;
目录
1.在CartController中,创建【添加商品到购物车】的方法:add()方法;
2.在CartServiceImpl实现类中编写添加商品到购物车的方法:add()方法;
(1.1)编写工具方法validProduct()方法,去检查:【前端传过来的商品id,商品表中是否有这个商品】、【商品是否是上架状态】、【商品的库存是否足够】;
(1.2)程序上下架的状态,我们为了【开发时,更加明确含义】、【有利于后期扩展】:把其定义在了Constant类中;(这是个很重要的开发习惯!!!)
(2.1)如果商品存在,商品是上架状态,商品库存足够时,这人需要根据购物车中是否有这个商品,来分情况处理;
(2.3)如果购物车中没有这个商品,那么我们就向购物车中添加这个商品;
(2.4)如果购物车中,已经有了这个商品;那么,我们就在原有的基础上,对商品的数量进行更新;
(2.5)和商品上下架同理,购物车中商品的选中状态,我们也在Constant类中定义了;
(3)因为,这个接口要求返回购物车列表,所以,这个方法调用了在开发【购物车列表】接口时,开发的list()方法;
(1)在CartMapper中定义【根据userId和ProductId,从Cart表中,查询数据】的方法:selectCartByUserIdAndProductId()方法;
1.一个容易犯错的点:报404错误,也可能是因为接口没有返回JSON格式的数据;
一:【添加商品到购物车】接口;
1.【添加商品到购物车】接口文档;
接口返回的是“购物车列表”;
说明:
(1)这个接口为什么要返回购物车列表?:我们每次向购物车添加商品后,购物车就会发生变化;即,我们的购物车肯定是需要刷新的;那么与其让其前端再去调用接口来获取最新的购物车列表,不如我们在这个接口就直接返回最新的购物车列表,这可以减少延迟,提高性能;(PS:购物车模块的其他接口,也是如此)
2.【添加商品到购物车】接口,在界面上的表现;
待写,项目上线后,再回来补充……
二:正式开发;
1.在CartController中,创建【添加商品到购物车】的方法:add()方法;
/** * 购物车模块:添加商品到购物车; * @param productId * @param count * @return */ @ApiOperation("添加商品到购物车") @PostMapping("/add") public ApiRestResponse add(@RequestParam("productId") Integer productId, @RequestParam("count") Integer count) { List<CartVO> cartVOList = cartService.add(UserFilter.currentUser.getId(), productId, count); return ApiRestResponse.success(cartVOList); }
说明:
(1) url,请求方式,参数,要符合接口文档的要求;
(2)因为,这个接口会被在【Spring Boot电商项目44:购物车模块二:统一校验当前是否有用户登录;】中编写的过滤器给处理;所以,我们可以通过UserFilter来获取当前登录用户;
(5)Service层的添加商品到购物车的方法,在下一部分介绍;
2.在CartServiceImpl实现类中编写添加商品到购物车的方法:add()方法;
/** * 添加商品到购物车 * @param userId * @param productId * @param count * @return */ @Override public List<CartVO> add(Integer userId, Integer productId, Integer count) { //调用工具方法,先看下【我们传的这个productId,在数据库中究竟有没有这个id的商品】; //然后,再看下商品是否是上架状态、商品库存是否足够; validProduct(productId, count); //然后,在看下购物车中,是否已经添加过了这个商品 Cart cart = cartMapper.selectCartByUserIdAndProductId(userId, productId); if (cart == null) {//如果该商品之前,不在购物车里;那么,我们就创建一个cart记录,添加到cart表中; cart = new Cart(); cart.setProductId(productId); cart.setUserId(userId); cart.setQuantity(count); cart.setSelected(Constant.CartIsSelected.CHECKED);//默认情况下,商品被添加到购物车后,就是选中状态 cartMapper.insertSelective(cart); } else {//如果该商品之前,就在购物车里了;那么,我们就去更新购物车中的这个商品,主要是对商品数量的叠加 int countNew = cart.getQuantity() + count; Cart cartNew = new Cart(); cartNew.setQuantity(countNew); cartNew.setId(cart.getId()); cartNew.setProductId(cart.getProductId()); cartNew.setUserId(cart.getUserId()); //至于商品是否设为选中,需要看具体的项目业务要求; // 我们这儿的策略,只要我们增加购物车的某个商品的数量了,就认为用户想买了,就把其设为选中状态; cartNew.setSelected(Constant.CartIsSelected.CHECKED); cartMapper.updateByPrimaryKeySelective(cartNew); } return this.list(userId); } /** * 工具方法;判断商品是否存在、商品是否是上架状态、商品库存是否足够; * @param productId * @param count