修改 system-service-app 导入的数据库脚本
This commit is contained in:
@@ -0,0 +1 @@
|
||||
package cn.iocoder.mall.searchservice.enums;
|
||||
@@ -0,0 +1,35 @@
|
||||
package cn.iocoder.mall.searchservice.enums.product;
|
||||
|
||||
/**
|
||||
* 搜索商品分页查询的排序字段枚举
|
||||
*/
|
||||
public enum SearchProductPageQuerySortFieldEnum {
|
||||
|
||||
/**
|
||||
* 购买价格
|
||||
*/
|
||||
BUY_PRICE("buyPrice");
|
||||
|
||||
/**
|
||||
* 字段
|
||||
*/
|
||||
private final String field;
|
||||
|
||||
SearchProductPageQuerySortFieldEnum(String field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return field;
|
||||
}
|
||||
|
||||
public static boolean contains(String field) {
|
||||
for (SearchProductPageQuerySortFieldEnum fieldEnum : values()) {
|
||||
if (field.equals(fieldEnum.getField())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
package cn.iocoder.mall.searchservice.convert.product;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.searchservice.dal.es.dataobject.ESProductDO;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductCreateBO;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductBO;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductSaveBO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
@Mapper
|
||||
public interface SearchProductConvert {
|
||||
@@ -23,8 +26,12 @@ public interface SearchProductConvert {
|
||||
@Mapping(source = "spu.picUrls", target = "picUrls")
|
||||
@Mapping(source = "spu.visible", target = "visible")
|
||||
@Mapping(source = "spu.sort", target = "sort")
|
||||
SearchProductCreateBO convert(ProductSpuRespDTO spu, ProductCategoryRespDTO category);
|
||||
SearchProductSaveBO convert(ProductSpuRespDTO spu, ProductCategoryRespDTO category);
|
||||
|
||||
ESProductDO convert(SearchProductCreateBO bean);
|
||||
ESProductDO convert(SearchProductSaveBO bean);
|
||||
|
||||
@Mapping(source = "content", target = "list")
|
||||
@Mapping(source = "getTotalElements", target = "total")
|
||||
PageResult<SearchProductBO> convert(Page<ESProductDO> searchPage);
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import cn.iocoder.mall.productservice.rpc.spu.ProductSpuRpc;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.mall.searchservice.convert.product.SearchProductConvert;
|
||||
import cn.iocoder.mall.searchservice.service.product.SearchProductService;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductCreateBO;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductSaveBO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -62,7 +62,7 @@ public class SearchProductManager {
|
||||
return false;
|
||||
}
|
||||
// 保存商品到 ES 中
|
||||
SearchProductCreateBO searchProductCreateBO = SearchProductConvert.INSTANCE.convert(
|
||||
SearchProductSaveBO searchProductCreateBO = SearchProductConvert.INSTANCE.convert(
|
||||
productSpuResult.getData(), getProductCategoryResult.getData());
|
||||
ProductSkuRespDTO productSku = listProductSkusResult.getData().stream()
|
||||
.min(Comparator.comparing(ProductSkuRespDTO::getPrice)).orElse(null);
|
||||
@@ -72,7 +72,7 @@ public class SearchProductManager {
|
||||
searchProductCreateBO.setOriginalPrice(productSku.getPrice());
|
||||
searchProductCreateBO.setBuyPrice(productSku.getPrice());
|
||||
searchProductCreateBO.setQuantity(productSku.getQuantity());
|
||||
searchProductService.createSearchProduct(searchProductCreateBO);
|
||||
searchProductService.saveSearchProduct(searchProductCreateBO);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,111 @@
|
||||
package cn.iocoder.mall.searchservice.service.product;
|
||||
|
||||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.common.framework.vo.SortingField;
|
||||
import cn.iocoder.mall.searchservice.convert.product.SearchProductConvert;
|
||||
import cn.iocoder.mall.searchservice.dal.es.dataobject.ESProductDO;
|
||||
import cn.iocoder.mall.searchservice.dal.es.repository.ESProductRepository;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductCreateBO;
|
||||
import cn.iocoder.mall.searchservice.enums.product.SearchProductPageQuerySortFieldEnum;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductBO;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductConditionBO;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductPageQueryBO;
|
||||
import cn.iocoder.mall.searchservice.service.product.bo.SearchProductSaveBO;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.search.aggregations.Aggregation;
|
||||
import org.elasticsearch.search.aggregations.AggregationBuilders;
|
||||
import org.elasticsearch.search.aggregations.bucket.terms.LongTerms;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class SearchProductService {
|
||||
|
||||
@Autowired
|
||||
private ESProductRepository productRepository;
|
||||
@Autowired
|
||||
private ElasticsearchTemplate elasticsearchTemplate; // 因为需要使用到聚合操作,只好引入 ElasticsearchTemplate 。
|
||||
|
||||
public void createSearchProduct(SearchProductCreateBO createBO) {
|
||||
ESProductDO productDO = SearchProductConvert.INSTANCE.convert(createBO);
|
||||
/**
|
||||
* 搜索商品分页结果
|
||||
*
|
||||
* @param pageQueryBO 分页查询条件
|
||||
* @return 商品信息
|
||||
*/
|
||||
public PageResult<SearchProductBO> getSearchPage(SearchProductPageQueryBO pageQueryBO) {
|
||||
checkSortFieldInvalid(pageQueryBO.getSorts());
|
||||
// 执行查询
|
||||
Page<ESProductDO> searchPage = productRepository.search(pageQueryBO.getCid(), pageQueryBO.getKeyword(),
|
||||
pageQueryBO.getPageNo(), pageQueryBO.getPageSize(), pageQueryBO.getSorts());
|
||||
// 转换结果
|
||||
return SearchProductConvert.INSTANCE.convert(searchPage);
|
||||
}
|
||||
|
||||
private void checkSortFieldInvalid(List<SortingField> sorts) {
|
||||
if (CollectionUtils.isEmpty(sorts)) {
|
||||
return;
|
||||
}
|
||||
sorts.forEach(sortingField -> Assert.isTrue(SearchProductPageQuerySortFieldEnum.contains(sortingField.getField()),
|
||||
String.format("排序字段(%s) 不在允许范围内", sortingField.getField())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存商品信息到 ES 中
|
||||
*
|
||||
* @param saveBO 商品信息
|
||||
*/
|
||||
public void saveSearchProduct(SearchProductSaveBO saveBO) {
|
||||
ESProductDO productDO = SearchProductConvert.INSTANCE.convert(saveBO);
|
||||
productRepository.save(productDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得指定关键字对应的搜索条件
|
||||
*
|
||||
* 在我们搜索商品时,需要获得关键字可选择的分类、品牌等等搜索条件,方便用户进一步检索
|
||||
*
|
||||
* @param keyword 关键字
|
||||
* @param fields 需要返回的搜索条件。目前可传入的参数为
|
||||
* 1. category :商品分类,会返回商品分类编号
|
||||
* @return 搜索条件
|
||||
*/
|
||||
public SearchProductConditionBO getSearchCondition(String keyword, Collection<String> fields) {
|
||||
// 创建 ES 搜索条件
|
||||
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
|
||||
// 筛选
|
||||
if (StringUtils.hasText(keyword)) { // 如果有 keyword ,就去匹配
|
||||
nativeSearchQueryBuilder.withQuery(QueryBuilders.multiMatchQuery(keyword,
|
||||
"name", "sellPoint", "categoryName"));
|
||||
} else {
|
||||
nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
|
||||
}
|
||||
// 聚合
|
||||
if (fields.contains("category")) { // 商品分类
|
||||
nativeSearchQueryBuilder.addAggregation(AggregationBuilders.terms("cids").field("cid"));
|
||||
}
|
||||
// 执行查询,返回结果
|
||||
return elasticsearchTemplate.query(nativeSearchQueryBuilder.build(), response -> {
|
||||
SearchProductConditionBO result = new SearchProductConditionBO();
|
||||
// categoryIds 聚合
|
||||
Aggregation categoryIdsAggregation = response.getAggregations().get("cids");
|
||||
if (categoryIdsAggregation != null) {
|
||||
result.setCids(new ArrayList<>());
|
||||
for (LongTerms.Bucket bucket : (((LongTerms) categoryIdsAggregation).getBuckets())) {
|
||||
result.getCids().add(bucket.getKeyAsNumber().intValue());
|
||||
}
|
||||
}
|
||||
// 返回结果
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package cn.iocoder.mall.searchservice.service.product.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 搜索商品 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class SearchProductBO {
|
||||
|
||||
private Integer id;
|
||||
|
||||
// ========== 基本信息 =========
|
||||
/**
|
||||
* SPU 名字
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 卖点
|
||||
*/
|
||||
private String sellPoint;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
private Integer cid;
|
||||
/**
|
||||
* 分类名
|
||||
*/
|
||||
private String categoryName;
|
||||
/**
|
||||
* 商品主图地数组
|
||||
*/
|
||||
private List<String> picUrls;
|
||||
|
||||
// ========== 其他信息 =========
|
||||
/**
|
||||
* 是否上架商品(是否可见)。
|
||||
*
|
||||
* true 为已上架
|
||||
* false 为已下架
|
||||
*/
|
||||
private Boolean visible;
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
private Integer sort;
|
||||
|
||||
// ========== Sku 相关字段 =========
|
||||
/**
|
||||
* 原价格,单位:分
|
||||
*/
|
||||
private Integer originalPrice;
|
||||
/**
|
||||
* 购买价格,单位:分。
|
||||
*/
|
||||
private Integer buyPrice;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
|
||||
// ========== 促销活动相关字段 =========
|
||||
// 目前只促销单体商品促销,目前仅限制折扣。
|
||||
/**
|
||||
* 促销活动编号
|
||||
*/
|
||||
private Integer promotionActivityId;
|
||||
/**
|
||||
* 促销活动标题
|
||||
*/
|
||||
private String promotionActivityTitle;
|
||||
/**
|
||||
* 促销活动类型
|
||||
*/
|
||||
private Integer promotionActivityType;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package cn.iocoder.mall.searchservice.service.product.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品搜索条件返回 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class SearchProductConditionBO {
|
||||
|
||||
/**
|
||||
* 商品分类数组
|
||||
*/
|
||||
private List<Integer> cids;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package cn.iocoder.mall.searchservice.service.product.bo;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageParam;
|
||||
import cn.iocoder.common.framework.vo.SortingField;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品检索分查询 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class SearchProductPageQueryBO extends PageParam {
|
||||
|
||||
/**
|
||||
* 分类编号
|
||||
*/
|
||||
private Integer cid;
|
||||
/**
|
||||
* 关键字
|
||||
*/
|
||||
private String keyword;
|
||||
/**
|
||||
* 排序字段数组
|
||||
*
|
||||
*
|
||||
*/
|
||||
private List<SortingField> sorts;
|
||||
|
||||
}
|
||||
@@ -6,11 +6,11 @@ import lombok.experimental.Accessors;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 搜索商品创建 BO
|
||||
* 搜索商品保存 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors
|
||||
public class SearchProductCreateBO {
|
||||
public class SearchProductSaveBO {
|
||||
|
||||
private Integer id;
|
||||
|
||||
Reference in New Issue
Block a user