谷粒商城实战笔记-131~132-商城业务-商品上架-构造sku检索属性和库存查询

一,131-商城业务-商品上架-构造sku检索属性

1,开发目标

这一节的主要内容是完成获取规格属性信息的功能

  • 从数据库中获取与 SPU 关联的所有规格属性。
  • 筛选出可被用于搜索的属性,并转换为 ES 所需的格式。
  • 注意点1:SPU的规格参数是这个SPU下所有SKU公用的,查询一次即可。
  • 注意点2:规程参数分为两类,一类是可搜索的,一类是不可搜索的。这里需要的是可搜索的规格参数。

2,详细设计

  • ① 从pms_product_attr_value表中根据spu_id查出这个spu下所有的属性。
  • ② 根据属性Id从属性表中pms_attr查询属性是否可搜索。
  • ③ 将可搜索的属性信息封装到Es的Java模型中。

2.1,根据spu_id获取所有的规格参数

List<ProductAttrValueEntity> baseAttrs = productAttrValueService.baseAttrList4Spu(spuId);

对应的Service实现非常简单。

	public List<ProductAttrValueEntity> baseAttrList4Spu(Long spuId) {

        List<ProductAttrValueEntity> attrValueEntityList = this.baseMapper.selectList(
                new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));

        return attrValueEntityList;
    }

2.2,根据上一步中查询结果进一步确认是否可搜索

汇总所有属性Id,一次性查询出其中所有可搜索的属性Id。

List<Long> attrIds = baseAttrs.stream().map(ProductAttrValueEntity::getAttrId).collect(Collectors.toList());

        // 查询可搜索的规格属性
        List<Long> searchAttrIds = attrService.selectSearchableAttrs(attrIds);

对应的Service实现如下。

	
    public List<Long> selectSearchableAttrs(List<Long> attrIds) {

        List<Long> searchAttrIds = this.baseMapper.selectSearchAttrIds(attrIds);

        return searchAttrIds;
    }

对应的Sql如下。

<select id="selectSearchAttrIds" resultType="java.lang.Long">

        SELECT attr_id FROM pms_attr WHERE attr_id IN
        <foreach collection="attrIds" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
        AND search_type = 1

</select>

注意,search_type = 1 表示这个属性可搜索。

2.3,将可搜索的属性封装到Java模型中

将前两步的结果结合起来,把spu下所有可搜索的属性封装到Java模型中。

        Set<Long> idSet = new HashSet<>(searchAttrIds);
        List<SkuEsModel.Attrs> attrsList = baseAttrs
                .stream().
                filter(item -> idSet.contains(item.getAttrId()))
                .map(item -> {
                    SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
                    BeanUtils.copyProperties(item, attrs);
                    return attrs;
                }).collect(Collectors.toList());

在这里插入图片描述

二,132-商城业务-商品上架-远程查询库存&泛型结果封装

1,开发目标

获取库存信息:

  • 通过远程调用库存服务,获取每个 SKU 的库存状态。
  • 库存状态用于确定 SKU 是否有货。

2,详细设计

  • ① 调用库存服务的接口
  • ② 库存服务根据sku_id查询库存量
  • ③ 根据查询结果填充模型

2.1 调用库存服务的接口

通过Feign调用库存服务的接口,并处理返回结果。

		List<Long> skuIdList = skuInfoEntities.stream()
                    .map(SkuInfoEntity::getSkuId)
                    .collect(Collectors.toList());
                    
            R skuHasStock = wareFeignService.getSkuHasStock(skuIdList);
            
            TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};
            stockMap = skuHasStock.getData(typeReference).stream()
                    .collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));

通过Feign将spu下所有的sku_id传递给库存服务。

2.2,库存服务根据sku_id查询库存量

① ware服务WareSkuController中定义供调用的接口。

	(value = "/hasStock")
    public R getSkuHasStock( List<Long> skuIds) {

        //skuId stock
        List<SkuHasStockVo> vos = wareSkuService.getSkuHasStock(skuIds);

        return R.ok().setData(vos);

    }

对应的Service实现如下。

	
    public List<SkuHasStockVo> getSkuHasStock(List<Long> skuIds) {

        List<SkuHasStockVo> skuHasStockVos = skuIds.stream().map(item -> {
            Long count = this.baseMapper.getSkuStock(item);
            SkuHasStockVo skuHasStockVo = new SkuHasStockVo();
            skuHasStockVo.setSkuId(item);
            skuHasStockVo.setHasStock(count == null?false:count > 0);
            return skuHasStockVo;
        }).collect(Collectors.toList());
        return skuHasStockVos;
    }

对应的Dao层Sql如下,逻辑非常简单,查询可用库存大于0的sku_id。

	<select id="listWareIdHasSkuStock" resultType="java.lang.Long">
        SELECT
            ware_id
        FROM
            wms_ware_sku
        WHERE
            sku_id = #{skuId}
          AND stock - stock_locked > 0
    </select>

2.3,根据查询结果填充模型

调用库存接口查询到结果之后,从响应R中取出数据,注意因为R本质是一个Map,所以需要将Map中的数据序列化为我们需要的类型,这里使用了阿里的FastJson工具包中的TypeReference完成这个任务。

			R skuHasStock = wareFeignService.getSkuHasStock(skuIdList);
            TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};
            stockMap = skuHasStock.getData(typeReference).stream()
                    .collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
	public <T> T getData(TypeReference<T> typeReference) {
		Object data = get("data");	//默认是map
		String jsonString = JSON.toJSONString(data);
		T t = JSON.parseObject(jsonString, typeReference);
		return t;
	}

拿到结果之后,在遍历Sku的循环体中填充库存信息。

			// 4.2 设置库存信息
            if (finalStockMap == null) {
                esModel.setHasStock(true);
            } else {
                esModel.setHasStock(finalStockMap.get(sku.getSkuId()));
            }

这样注意从响应中取得结果的方式,是开发中常用的技巧。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
购物商城的Spu-Sku数据库设计主要是为了管理商品库存和销售信息。Spu(Standard Product Unit)是商品的标准产品单位,通常指的是一组具有相同特征但可能有不同规格的商品,例如同一款衣服的不同颜色或尺码。Sku(Stock Keeping Unit)是商品库存管理单位,是对Spu的具体细分,用于区分不同规格或属性商品。 在数据库设计,可以建立两个主要的表:Spu表和Sku表。Spu表用于存储商品的基本信息,包括商品的名称、描述、品牌、分类等。此外,可以为Spu表添加一些扩展字段,例如商品的图片、销售状态等。 Sku表用于存储商品的具体规格和库存信息,其包括Spu的外键关联、商品属性、规格、价格和库存数量等。通过外键关联,可以将Sku与其对应的Spu关联起来,实现Spu与Sku的多对一关系。同时,可以在Sku添加一些扩展字段,例如商品的条形码、上架时间等。 为了提高查询效率,可以在Sku添加索引,例如根据商品的价格、库存数量、销售状态等字段进行索引,以快速获取满足条件的商品信息。 此外,为了提高系统的可维护性和可扩展性,可以添加一些辅助表,例如属性表和属性值表,用于管理商品属性信息。属性表用于存储商品属性名称,属性值表用于存储属性的具体取值范围。 总之,购物商城的Spu-Sku数据库设计需要考虑Spu和Sku之间的关联关系,以及商品的基本信息和规格信息的存储和管理。通过合理的设计和优化索引,可以提高系统的查询性能和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小手追梦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值