谷粒商城实战笔记-277~278-商城业务-订单服务-构造订单和订单明细
文章目录
- 一,277-商城业务-订单服务-构造订单数据
- 1,构建订单信息
- 二,278-商城业务-订单服务-构造订单项数据
- `builderOrderItems` 方法
- `getUserCartItems` 方法
点击conform页面的提交订单,本质上是要创建一个订单,一定要牢记这个核心任务。
一个订单的基本组成:
- 订单号
- 一个订单有订单头和订单明细构成,订单项就是订单明细,明细的维度是sku维度
- 一个订单头对应多个订单明细
- 收货人信息
- 订单金额
- 支付方式
- 运费
一,277-商城业务-订单服务-构造订单数据
这一节的主要内容是构造订单数据:
- 生成订单号
- 设置运费信息
- 设置收货人地址信息
- 生成订单项信息,一个订单有订单头和订单明细构成,订单项就是订单明细,明细的维度是sku维度
1,构建订单信息
private OrderEntity builderOrder(String orderSn) {//获取当前用户登录信息MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();OrderEntity orderEntity = new OrderEntity();orderEntity.setMemberId(memberResponseVo.getId());orderEntity.setOrderSn(orderSn);orderEntity.setMemberUsername(memberResponseVo.getUsername());OrderSubmitVo orderSubmitVo = confirmVoThreadLocal.get();//远程获取收货地址和运费信息R fareAddressVo = wmsFeignService.getFare(orderSubmitVo.getAddrId());FareVo fareResp = fareAddressVo.getData("data", new TypeReference<FareVo>() {});//获取到运费信息BigDecimal fare = fareResp.getFare();orderEntity.setFreightAmount(fare);//获取到收货地址信息MemberAddressVo address = fareResp.getAddress();//设置收货人信息orderEntity.setReceiverName(address.getName());orderEntity.setReceiverPhone(address.getPhone());orderEntity.setReceiverPostCode(address.getPostCode());orderEntity.setReceiverProvince(address.getProvince());orderEntity.setReceiverCity(address.getCity());orderEntity.setReceiverRegion(address.getRegion());orderEntity.setReceiverDetailAddress(address.getDetailAddress());//设置订单相关的状态信息orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());orderEntity.setAutoConfirmDay(7);orderEntity.setConfirmStatus(0);return orderEntity;}
这段代码定义了一个名为 builderOrder
的私有方法,其主要作用是构建一个新的订单实体(OrderEntity
)对象,并填充该对象的属性。
-
获取用户信息:通过
LoginUserInterceptor.loginUser.get()
获取当前登录用户的信息,这些信息将用于设置订单的会员ID、用户名等。 -
初始化订单实体:创建一个新的
OrderEntity
对象,并设置订单号(orderSn
),这是订单的唯一标识。 -
获取订单提交信息:从
confirmVoThreadLocal
线程局部变量中获取订单提交信息(OrderSubmitVo
),这可能包含了用户选择的收货地址ID等信息。 -
远程服务调用:使用
wmsFeignService.getFare
方法调用库存管理服务(可能是一个远程微服务),根据用户选择的地址ID获取运费信息。 -
解析运费信息:从远程服务返回的结果中解析出运费(
fare
)和收货地址信息(address
)。 -
设置运费:将获取到的运费设置到订单实体的
freightAmount
属性。 -
设置收货地址信息:将解析出的收货地址信息设置到订单实体的相关属性中,包括收货人姓名、电话、邮编、省市区信息和详细地址。
-
设置订单状态:初始化订单的状态信息,例如设置订单状态为
CREATE_NEW
(可能是一个枚举值,表示新创建的订单),自动确认天数为7天,确认状态为0(可能表示未确认)。 -
返回订单实体:方法最后返回构建好的订单实体对象,这个对象可以被用于后续的订单保存操作。
builderOrder
方法负责根据当前登录用户的信息和提交的订单数据,构建一个新的订单实体,并填充所有必要的属性,为订单的创建和保存做准备。
二,278-商城业务-订单服务-构造订单项数据
这一节远程调用购物车接口,获取用户勾选的商品,生成订单明细,虽然不是很严谨,因为用户提交订单前可能修改购物车,应该以用户修改前提交订单时为准。
订单详细包含如下逻辑:
- sku信息,包括 SKU 名称、图片、价格和数量
- spu信息,包括 SPU ID、名称、品牌和分类 ID
- 设置商品的积分信息,计算商品的积分和成长值,通常是基于商品价格和数量,并将积分信息设置到订单项实体中
- 设置订单项的价格信息,初始化优惠金额、优惠券金额和积分金额为零;计算实际金额,即商品原价减去各种优惠后的金额,并设置到订单项实体中
public List<OrderItemEntity> builderOrderItems(String orderSn) {List<OrderItemEntity> orderItemEntityList = new ArrayList<>();//最后确定每个购物项的价格List<OrderItemVo> currentCartItems = cartFeignService.getCurrentCartItems();if (currentCartItems != null && currentCartItems.size() > 0) {orderItemEntityList = currentCartItems.stream().map((items) -> {//构建订单项数据OrderItemEntity orderItemEntity = builderOrderItem(items);orderItemEntity.setOrderSn(orderSn);return orderItemEntity;}).collect(Collectors.toList());}return orderItemEntityList;}private OrderItemEntity builderOrderItem(OrderItemVo items) {OrderItemEntity orderItemEntity = new OrderItemEntity();//1、商品的spu信息Long skuId = items.getSkuId();//获取spu的信息R spuInfo = productFeignService.getSpuInfoBySkuId(skuId);SpuInfoVo spuInfoData = spuInfo.getData("data", new TypeReference<SpuInfoVo>() {});orderItemEntity.setSpuId(spuInfoData.getId());orderItemEntity.setSpuName(spuInfoData.getSpuName());orderItemEntity.setSpuBrand(spuInfoData.getBrandName());orderItemEntity.setCategoryId(spuInfoData.getCatalogId());//2、商品的sku信息orderItemEntity.setSkuId(skuId);orderItemEntity.setSkuName(items.getTitle());orderItemEntity.setSkuPic(items.getImage());orderItemEntity.setSkuPrice(items.getPrice());orderItemEntity.setSkuQuantity(items.getCount());//使用StringUtils.collectionToDelimitedString将list集合转换为StringString skuAttrValues = StringUtils.collectionToDelimitedString(items.getSkuAttrValues(), ";");orderItemEntity.setSkuAttrsVals(skuAttrValues);//3、商品的优惠信息//4、商品的积分信息orderItemEntity.setGiftGrowth(items.getPrice().multiply(new BigDecimal(items.getCount())).intValue());orderItemEntity.setGiftIntegration(items.getPrice().multiply(new BigDecimal(items.getCount())).intValue());//5、订单项的价格信息orderItemEntity.setPromotionAmount(BigDecimal.ZERO);orderItemEntity.setCouponAmount(BigDecimal.ZERO);orderItemEntity.setIntegrationAmount(BigDecimal.ZERO);//当前订单项的实际金额.总额 - 各种优惠价格//原来的价格BigDecimal origin = orderItemEntity.getSkuPrice().multiply(new BigDecimal(orderItemEntity.getSkuQuantity().toString()));//原价减去优惠价得到最终的价格BigDecimal subtract = origin.subtract(orderItemEntity.getCouponAmount()).subtract(orderItemEntity.getPromotionAmount()).subtract(orderItemEntity.getIntegrationAmount());orderItemEntity.setRealAmount(subtract);return orderItemEntity;}
购物车服务提供的查询勾选的购物项接口逻辑如下。
public List<CartItemVo> getUserCartItems() {List<CartItemVo> cartItemVoList = new ArrayList<>();//获取当前用户登录的信息UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();//如果用户未登录直接返回nullif (userInfoTo.getUserId() == null) {return null;} else {//获取购物车项String cartKey = CART_PREFIX + userInfoTo.getUserId();//获取所有的List<CartItemVo> cartItems = getCartItems(cartKey);if (cartItems == null) {throw new CartExceptionHandler();}//筛选出选中的cartItemVoList = cartItems.stream().filter(items -> items.getCheck()).map(item -> {//更新为最新的价格(查询数据库)BigDecimal price = productFeignService.getPrice(item.getSkuId());item.setPrice(price);return item;}).collect(Collectors.toList());}return cartItemVoList;}
builderOrderItems
方法
这个方法的作用是构建订单项列表(List<OrderItemEntity>
),这些订单项将与主订单关联。具体步骤如下:
-
初始化订单项列表:创建一个新的
ArrayList<OrderItemEntity>
来存储订单项实体。 -
获取当前用户的购物车项目:通过调用
cartFeignService.getCurrentCartItems()
获取用户勾选的购物车项目列表。这个方法可能是远程调用购物车服务的接口。 -
检查购物车项目:如果获取到的购物车项目列表不为空,那么将遍历这个列表:
- 对于每个
OrderItemVo
对象,调用builderOrderItem(items)
方法来构建一个订单项实体OrderItemEntity
。 - 设置订单项实体的订单号
orderSn
。
- 对于每个
-
收集订单项:使用 Java 8 的 Stream API 来处理和收集订单项,最后返回构建好的订单项列表。
getUserCartItems
方法
这个方法的作用是获取当前登录用户勾选的购物车项目,并更新价格信息。具体步骤如下:
-
初始化购物车项目列表:创建一个新的
ArrayList<CartItemVo>
来存储购物车项目。 -
获取当前用户登录信息:通过
CartInterceptor.toThreadLocal.get()
获取当前用户信息。 -
检查用户登录状态:如果用户未登录,则直接返回
null
。 -
获取购物车项目:如果用户已登录,构建购物车键
CART_PREFIX + userId
并获取所有购物车项目。 -
筛选勾选的项目:使用 Stream API 筛选出勾选的购物车项目。
-
更新价格信息:对于每个勾选的购物车项目,调用
productFeignService.getPrice(item.getSkuId())
来获取最新的价格,并更新项目的价格信息。 -
收集并返回结果:使用 Stream API 收集更新过价格的购物车项目,并返回列表。
builderOrderItems
方法是订单服务的一部分,负责根据用户勾选的购物车项目构建订单项。
而 getUserCartItems
方法是购物车服务的一部分,负责获取并更新用户勾选的购物车项目的价格信息。这两个方法在订单创建流程中协同工作,确保订单包含正确的商品和价格信息。