建议阅读前,先阅读《商城表设计-购物车》相关文档 我们的购物车只有一个表:`tz_basket` 非常简单,但是关联了非常多的表。比如: - 购物车有商品,关联商品表 - 每个商品都有sku,关联sku表 - 一个购物车有多个店铺的商品,关联店铺表 - 一个购物车肯定是和用户有关的,关联用户表 我们对商品进行添加,修改,其实都很简单,最为让人难以理解的是如何将这些字段进行组合,关联满减满折等一系列的活动。 我们先来看下是如何获取商品信息的 ```java @PostMapping("/info") @ApiOperation(value = "获取用户购物车信息", notes = "获取用户购物车信息,参数为用户选中的活动项数组,以购物车id为key") public ResponseEntity<List<ShopCartDto>> info(@RequestBody Map<Long, ShopCartParam> basketIdShopCartParamMap) { String userId = SecurityUtils.getUser().getUserId(); // 更新购物车信息, if (MapUtil.isNotEmpty(basketIdShopCartParamMap)) { basketService.updateBasketByShopCartParam(userId, basketIdShopCartParamMap); } // 拿到购物车的所有item List<ShopCartItemDto> shopCartItems = basketService.getShopCartItems(userId); return ResponseEntity.ok(basketService.getShopCarts(shopCartItems)); } ``` 这里面传了一个参数:`Map<Long, ShopCartParam> basketIdShopCartParamMap` 这里是当用户改变了某件商品的满减满折活动时,重新改变满减满折信息以后计算加个的一个方法。当然在开源是没有这个满减模块的,只有思路,具体实现需要靠自己了。 我们继续往下看,这里面`basketService.getShopCartItems(userId)`使用的直接是从数据库中获取的数据,而真正对满减满折、店铺等进行排列组合的,在于`basketService.getShopCarts(shopCartItems)` 这个方法。 我们进到`getShopCarts`方法内部,可以查看到一行代码`applicationContext.publishEvent(new ShopCartEvent(shopCart, shopCartItemDtoList));`,这里使用的事件的模式。这个事件的主要作用是用于对模块之间的解耦,比如我们清楚的知道当购物车需要计算价格的时候,需要满减模块的配合,进行“装饰”。最后将装饰回来的东西,返回给前端。 我们现在看看购物车返回的数据`ResponseEntity<List<ShopCartDto>>`,我们清楚一个购物车是分多个店铺的,每一个店铺就是一个`ShopCartDto`,我们看下这个`bean`。 ```java @Data public class ShopCartDto implements Serializable { @ApiModelProperty(value = "店铺ID", required = true) private Long shopId; @ApiModelProperty(value = "店铺名称", required = true) private String shopName; @ApiModelProperty(value = "购物车满减活动携带的商品", required = true) private List<ShopCartItemDiscountDto> shopCartItemDiscounts; } ``` 其实一个店铺下面是有多个商品的,但是根据京东的划分,每当有满减之类的活动时,满减活动的商品总是要归到一类的,所以,每个店铺下面是多个满减活动(`List<ShopCartItemDiscountDto>`),满减活动下面是多个商品(购物项`List<ShopCartItemDto>`),到此你就能明白了`ShopCartItemDiscountDto` 里面的`ChooseDiscountItemDto` 是什么东西了,这个是选中的满减项。 ```java public class ShopCartItemDiscountDto implements Serializable { @ApiModelProperty(value = "已选满减项", required = true) private ChooseDiscountItemDto chooseDiscountItemDto; @ApiModelProperty(value = "商品列表") private List<ShopCartItemDto> shopCartItems; } ``` 我们再留意`ShopCartItemDto` 这个`bean` ,发现还有这个东西: ```java @ApiModelProperty("参与满减活动列表") private List<DiscountDto> discounts = new ArrayList<>(); ``` 其实购物车的每个购物项,都是有很多个满减的活动的,可以自主选择满减活动,然后进行组合,生成新的优惠。而在这选择新的活动类型时,就需要购物车就行新的价格计算。这也就是为什么获取用户购物车信息,也就是`/info`接口需要一个这个参数的原因了`Map<Long, ShopCartParam> basketIdShopCartParamMap`