修改 system-service-app 导入的数据库脚本

This commit is contained in:
YunaiV
2020-08-01 17:37:25 +08:00
parent 8646d0a69e
commit d0ce6090ad
42 changed files with 328 additions and 1099 deletions

View File

@@ -0,0 +1 @@
package cn.iocoder.mall.searchservice.enums;

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
});
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;