谷粒商城实战笔记-277~278-商城业务-订单服务-构造订单和订单明细

点击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)对象,并填充该对象的属性。

  1. 获取用户信息:通过 LoginUserInterceptor.loginUser.get() 获取当前登录用户的信息,这些信息将用于设置订单的会员ID、用户名等。

  2. 初始化订单实体:创建一个新的 OrderEntity 对象,并设置订单号(orderSn),这是订单的唯一标识。

  3. 获取订单提交信息:从 confirmVoThreadLocal 线程局部变量中获取订单提交信息(OrderSubmitVo),这可能包含了用户选择的收货地址ID等信息。

  4. 远程服务调用:使用 wmsFeignService.getFare 方法调用库存管理服务(可能是一个远程微服务),根据用户选择的地址ID获取运费信息。

  5. 解析运费信息:从远程服务返回的结果中解析出运费(fare)和收货地址信息(address)。

  6. 设置运费:将获取到的运费设置到订单实体的 freightAmount 属性。

  7. 设置收货地址信息:将解析出的收货地址信息设置到订单实体的相关属性中,包括收货人姓名、电话、邮编、省市区信息和详细地址。

  8. 设置订单状态:初始化订单的状态信息,例如设置订单状态为 CREATE_NEW(可能是一个枚举值,表示新创建的订单),自动确认天数为7天,确认状态为0(可能表示未确认)。

  9. 返回订单实体:方法最后返回构建好的订单实体对象,这个对象可以被用于后续的订单保存操作。

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>),这些订单项将与主订单关联。具体步骤如下:

  1. 初始化订单项列表:创建一个新的 ArrayList<OrderItemEntity> 来存储订单项实体。

  2. 获取当前用户的购物车项目:通过调用 cartFeignService.getCurrentCartItems() 获取用户勾选的购物车项目列表。这个方法可能是远程调用购物车服务的接口。

  3. 检查购物车项目:如果获取到的购物车项目列表不为空,那么将遍历这个列表:

    • 对于每个 OrderItemVo 对象,调用 builderOrderItem(items) 方法来构建一个订单项实体 OrderItemEntity
    • 设置订单项实体的订单号 orderSn
  4. 收集订单项:使用 Java 8 的 Stream API 来处理和收集订单项,最后返回构建好的订单项列表。

getUserCartItems 方法

这个方法的作用是获取当前登录用户勾选的购物车项目,并更新价格信息。具体步骤如下:

  1. 初始化购物车项目列表:创建一个新的 ArrayList<CartItemVo> 来存储购物车项目。

  2. 获取当前用户登录信息:通过 CartInterceptor.toThreadLocal.get() 获取当前用户信息。

  3. 检查用户登录状态:如果用户未登录,则直接返回 null

  4. 获取购物车项目:如果用户已登录,构建购物车键 CART_PREFIX + userId 并获取所有购物车项目。

  5. 筛选勾选的项目:使用 Stream API 筛选出勾选的购物车项目。

  6. 更新价格信息:对于每个勾选的购物车项目,调用 productFeignService.getPrice(item.getSkuId()) 来获取最新的价格,并更新项目的价格信息。

  7. 收集并返回结果:使用 Stream API 收集更新过价格的购物车项目,并返回列表。

builderOrderItems 方法是订单服务的一部分,负责根据用户勾选的购物车项目构建订单项。

getUserCartItems 方法是购物车服务的一部分,负责获取并更新用户勾选的购物车项目的价格信息。这两个方法在订单创建流程中协同工作,确保订单包含正确的商品和价格信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小手追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值