文章目录
点击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集合转换为String
String 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();
//如果用户未登录直接返回null
if (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
方法是购物车服务的一部分,负责获取并更新用户勾选的购物车项目的价格信息。这两个方法在订单创建流程中协同工作,确保订单包含正确的商品和价格信息。