[Función empresarial 84] Aplicación de ejemplo de microservicio SpringCloud-ElasticSearch-Kibanan-Electronic Commerce

1. Función de listado de productos

ElasticSearch realiza el proceso de búsqueda de texto completo en el sistema del centro comercial.

imagen.png

1. Modelo ES de productos básicos

Relación de mapeo de productos

PUT product 
{
    
    
	"mappings": {
    
    
		"properties": {
    
    
			"skuId": {
    
    
				"type": "long"
			},
			"spuId": {
    
    
				"type": "keyword"
			},
			"skuTitle": {
    
    
				"type": "text",
				"analyzer": "ik_smart"
			},
			"skuPrice": {
    
    
				"type": "keyword"
			},
			"skuImg": {
    
    
				"type": "keyword",
				"index": "false",
				"doc_values": "false"
			},
			"saleCount": {
    
    
				"type": "long"
			},
			"hasStock": {
    
    
				"type": "boolean"
			},
			"hotScore": {
    
    
				"type": "long"
			},
			"brandId": {
    
    
				"type": "long"
			},
			"catalogId": {
    
    
				"type": "long"
			},
			"brandName": {
    
    
				"type": "keyword",
				"index": "false",
				"doc_values": "false"
			},
			"brandImg": {
    
    
				"type": "keyword",
				"index": "false",
				"doc_values": "false"
			},
			"catalogName": {
    
    
				"type": "keyword",
				"index": "false",
				"doc_values": "false"
			},
			"attrs": {
    
    
				"type": "nested",
				"properties": {
    
    
					"attrId": {
    
    
						"type": "long"
					},
					"attrName": {
    
    
						"type": "keyword",
						"index": "false",
						"doc_values": "false"
					},
					"attrValue": {
    
    
						"type": "keyword"
					}
				}
			}
		}
	}
}

2.tipo de datos neteados

En el ejemplo anterior, el tipo netsted evita que los tres valores de campo en nuestro atributo de propiedades sean del mismo tipo y sus contenidos no coincidirán de manera confusa.

Dirección del sitio web oficial de referencia: https://www.elastic.co/guide/en/elasticsearch/reference/7.4/nested.html

3. Implementar la función de listado.

3.1 Crear modelo ES

Haga clic en la función de estante para pasar el spuId al fondo. Necesitamos consultar la información correspondiente de acuerdo con el SpuID, luego encapsularla en un objeto Modelo personalizado y luego pasar el objeto al servicio de búsqueda del centro comercial, por lo que debemos definir dicho objeto modelo primero

@Data
public class SkuESModel {
    
    
    private Long skuId;
    private Long spuId;
    private String subTitle;
    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;
  
    @Data
    public static class Attrs{
    
    
       private Long attrId;
       private String attrName;
       private String attrValue;
    }

}

3.2 Implementación de la lógica de listado

capa controladora

/**
 * spu信息
 *
 */
@RestController
@RequestMapping("product/spuinfo")
public class SpuInfoController {
    
    
    @Autowired
    private SpuInfoService spuInfoService;

    /**
     * app/product/spuinfo/6/up
     * 商品的上架功能
     * 传递过来一个spuID
     * 我们就需要根据SPUID查询出需要存储在ElasticSearch中的数据
     * 然后把数据存储到ELasticSearch中,并修改该SPU的状态为上架
     */
    @PostMapping("/{spuId}/up")
    public R spuUp(@PathVariable("spuId") Long spuId){
    
    
        spuInfoService.up(spuId);
        return R.ok();
    }
}

Implementación del método de la capa de servicio central

Se ignora la llamada a otros métodos de clase de implementación bajo el mismo módulo.

/**
     * 实现商品上架--》商品相关数据存储到ElasticSearch中
     * 1.根据SpuID查询出相关的信息
     *   封装到对应的对象中
     * 2.将封装的数据存储到ElasticSearch中--》调用mall-search的远程接口
     * 3.更新SpuID对应的状态--》上架
     *
     * @param spuId
     */
    @Override
    public void up(Long spuId) {
    
    
        // 1.根据spuId查询相关的信息 封装到SkuESModel对象中
        List<SkuESModel> skuEs = new ArrayList<>();
        // 根据spuID找到对应的SKU信息
        List<SkuInfoEntity> skus = skuInfoService.getSkusBySpuId(spuId);

        // 对应的规格参数  根据spuId来查询规格参数信息
        List<SkuESModel.Attrs> attrsModel = getAttrsModel(spuId);
        // 需要根据所有的skuId获取对应的库存信息---》远程调用
        List<Long> skuIds = skus.stream().map(sku -> {
    
    
            return sku.getSkuId();
        }).collect(Collectors.toList());
        Map<Long, Boolean> skusHasStockMap = getSkusHasStock(skuIds);
        // 2.远程调用mall-search的服务,将SukESModel中的数据存储到ES中
        List<SkuESModel> skuESModels = skus.stream().map(item -> {
    
    
            SkuESModel model = new SkuESModel();
            // 先实现属性的复制
            BeanUtils.copyProperties(item,model);
            model.setSubTitle(item.getSkuTitle());
            model.setSkuPrice(item.getPrice());

            // hasStock 是否有库存 --》 库存系统查询  一次远程调用获取所有的skuId对应的库存信息
            if(skusHasStockMap == null){
    
    
                model.setHasStock(true);
            }else{
    
    
                model.setHasStock(skusHasStockMap.get(item.getSkuId()));
            }
            // hotScore 热度分 --> 默认给0即可
            model.setHotScore(0l);
            // 品牌和类型的名称
            BrandEntity brand = brandService.getById(item.getBrandId());
            CategoryEntity category = categoryService.getById(item.getCatalogId());
            model.setBrandName(brand.getName());
            model.setBrandImg(brand.getLogo());
            model.setCatalogName(category.getName());
            // 需要存储的规格数据
            model.setAttrs(attrsModel);

            return model;
        }).collect(Collectors.toList());
        // 将SkuESModel中的数据存储到ES中
        R r = searchFeginService.productStatusUp(skuESModels);
        // 3.更新SPUID对应的状态
        // 根据对应的状态更新商品的状态
        log.info("----->ES操作完成:{}" ,r.getCode());
        System.out.println("-------------->"+r.getCode());
        if(r.getCode() == 0){
    
    
            // 远程调用成功  更新商品的状态为 上架
            baseMapper.updateSpuStatusUp(spuId, ProductConstant.StatusEnum.SPU_UP.getCode());
        }else{
    
    
            // 远程调用失败
        }
    }

Feign llama a otros módulos de microservicio de forma remota

Cree una interfaz en el módulo que actualmente necesita llamar al microservicio remoto, busque el microservicio llamado correspondiente a través de la anotación @FeignClient ("mall-search") y luego agregue el nombre del método requerido y la ruta del parámetro formal de la capa del controlador del llamado microservicio Una vez que todo se copia, se puede completar la llamada remota.

@FeignClient("mall-search")
public interface SearchFeginService {
    
    

    @PostMapping("/search/save/product")
    public R productStatusUp(@RequestBody List<SkuESModel> skuESModels);
}

La capa de controlador del módulo de microservicio llamado

/**
 *
 * 存储商城数据到ElasticSearch的服务
 */
@Slf4j
@RequestMapping("/search/save")
@RestController
public class ElasticSearchSaveController {
    
    

    @Autowired
    private ElasticSearchSaveService service;

    /**
     * 存储商品上架信息到ElasticSearch服务的接口
     * @return
     */
    @PostMapping("/product")
    public R productStatusUp(@RequestBody List<SkuESModel> skuESModels){
    
    
        Boolean b = false;
        try {
    
    
            b = service.productStatusUp(skuESModels);
        } catch (IOException e) {
    
    
           // e.printStackTrace();
            log.error("ElasticSearch商品上架错误:{}",e);
            return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(), BizCodeEnume.PRODUCT_UP_EXCEPTION.getMsg());
        }
        if(b){
    
    
            return R.ok();
        }
        return R.error(BizCodeEnume.PRODUCT_UP_EXCEPTION.getCode(), BizCodeEnume.PRODUCT_UP_EXCEPTION.getMsg());
    }
    

Supongo que te gusta

Origin blog.csdn.net/studyday1/article/details/132512259
Recomendado
Clasificación