以始为终
这几讲的内容是完成商品上架功能。
商品上架的业务逻辑本身非常简单,主要有两个任务:
- ①将SPU关联的所有SKU信息存储到ES中,以提供给前端检索
- ②将spu的状态改为
已上架
。
要封装为ES中product索引对应的mapping结构,细节比较多,调用多个微服务,有一定的复杂度。
1,建立Java模型
根据ES索引Mapping创建Java模型,这是第一步,也是非常关键的一部,所有的开发都围绕这个模型进行。
但是在mapping已经确定的情况下,Java模型的创建是直截了当的。
把Java模型命名为SkuEsModel
。
package com.atguigu.common.es;
import lombok.Data;
import java.math.BigDecimal;
public class SkuEsModel {
private Long skuId;
private Long spuId;
private String skuTitle;
private BigDecimal skuPrice;
private String skuImg;
private Long saleCount;
private Boolean hasStock;
private Long hotScore;
private Long brandId;
private Long catalogId;
private String brandName;
private String brandImg;
private String catalogName;
private List<Attrs> attrs;
public static class Attrs {
private Long attrId;
private String attrName;
private String attrValue;
}
}
2,开发详细设计
在写代码前,一定要把需求理解清楚,编写详细设计文档,磨刀不误砍柴工。
这个接口的功能是将商品的 SKU 信息及相关的属性同步到 Elasticsearch (ES) 索引中,以便进行高效的搜索。
该过程涉及到从数据库中获取 SKU 信息、SPU规格属性信息、库存信息,并将这些信息格式化为 ES 所需的结构,最后将这些信息发送给 ES 进行索引。
注意,是以SKU为单位组织数据,一个SKU对应一个SkuEsModel ,对应一个ES文档。
2.1 主要功能
-
获取 SKU 信息:
- 从数据库中获取指定 SPU (Standard Product Unit) ID 下的所有 SKU 信息。
- 包括 SKU 的价格、默认图片等基本信息。
-
获取规格属性信息:
- 从数据库中获取与 SPU 关联的所有规格属性。
- 筛选出可被用于搜索的属性,并转换为 ES 所需的格式。
- 注意SPU的规格参数是这个SPU下所有SKU公用的,查询一次即可
-
获取库存信息:
- 通过远程调用库存服务,获取每个 SKU 的库存状态。
- 库存状态用于确定 SKU 是否有货。
-
格式化 SKU 信息:
- 将 SKU 信息、规格属性信息、库存信息格式化为 ES 所需的结构。
- 包括 SKU 价格、图片、库存状态、品牌信息、分类信息、规格属性等。
-
发送数据到 ES:
- 将格式化后的 SKU 信息发送给 ES 服务进行索引。
- 根据 ES 的响应更新 SPU 的状态。
2.2 详细设计
-
获取 SKU 信息:
- 函数:
getSkusBySpuId
- 输入:
spuId
(Long) - 输出:
List<SkuInfoEntity>
(包含 SKU 的基本信息)
- 函数:
-
获取规格属性信息:
- 函数:
baseAttrList4Spu
- 输入:
spuId
(Long) - 输出:
List<ProductAttrValueEntity>
(包含 SPU 的规格属性信息) - 筛选可搜索属性:
- 函数:
selectSearchableAttrs
- 输入:
List<Long> attrIds
- 输出:
List<Long>
(可搜索的属性 ID) - 转换为 ES 属性格式:
- 函数:
stream
+filter
+map
- 输入:
List<ProductAttrValueEntity>
- 输出:
List<SkuEsModel.Attrs>
(转换后的属性列表)
- 函数:
- 函数:
- 函数:
-
获取库存信息:
- 远程调用:
wareFeignService.getSkuHasStock
- 输入:
List<Long> skuIdList
- 输出:
Map<Long, Boolean>
(库存状态映射)
- 远程调用:
-
格式化 SKU 信息:
- 函数:
stream
+map
- 输入:
List<SkuInfoEntity>
- 输出:
List<SkuEsModel>
(ES 所需的 SKU 信息) - 具体操作:
- 复制 SKU 的基本信息到
SkuEsModel
- 设置 SKU 的价格、图片、库存状态
- 获取品牌信息和分类信息
- 设置 SKU 的规格属性
- 复制 SKU 的基本信息到
- 函数:
-
发送数据到 ES:
- 远程调用:
searchFeignService.productStatusUp
- 输入:
List<SkuEsModel>
- 输出:
R
(ES 的响应) - 根据响应更新 SPU 状态:
- 函数:
updaSpuStatus
- 输入:
spuId
(Long),status
(Integer) - 输出: 更新 SPU 的状态
- 函数:
- 远程调用:
2.3 异常处理
- 远程调用失败:
- 日志记录错误信息。
- 可以考虑重试机制和接口幂等性。
2.4 技术细节
-
类和方法:
SkuInfoEntity
: SKU 信息实体类。ProductAttrValueEntity
: 产品规格属性实体类。SkuEsModel
: 用于 ES 的 SKU 模型类。SkuEsModel.Attrs
: SKU 模型中的属性嵌套类。BrandEntity
: 品牌信息实体类。CategoryEntity
: 分类信息实体类。SkuHasStockVo
: 库存状态 VO。R
: 统一的响应封装类。TypeReference
: 用于泛型类型的引用。
-
依赖服务:
skuInfoService
: SKU 信息服务。productAttrValueService
: 产品规格属性服务。attrService
: 属性服务。brandService
: 品牌信息服务。categoryService
: 分类信息服务。wareFeignService
: 库存远程服务。searchFeignService
: ES 索引远程服务。
2.5 注意事项
- 在处理远程调用时,应考虑网络延迟和故障的可能性,并适当处理异常情况。
- 在格式化 SKU 信息时,应确保所有必要的信息都已正确填充,以避免 ES 索引中的数据不完整。
- 在更新 SPU 状态时,应确保操作的原子性和一致性,避免并发问题。