diff --git a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/sku/ProductSkuConvert.java b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/sku/ProductSkuConvert.java index 2d3848cb2..d2b22984d 100644 --- a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/sku/ProductSkuConvert.java +++ b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/convert/sku/ProductSkuConvert.java @@ -36,8 +36,8 @@ public interface ProductSkuConvert { List convertList03(List list); @Named("translateAttrValueIdsFromString") - default List translateAttrValueIdsFromString(String attrValueIdsStar) { - return StringUtils.split(attrValueIdsStar, ","); + default List translateAttrValueIdsFromString(String attrValueIdsStar) { + return StringUtils.splitToInt(attrValueIdsStar, ","); } @Named("translateAttrValueIdsFromList") diff --git a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/service/sku/bo/ProductSkuBO.java b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/service/sku/bo/ProductSkuBO.java index f934f964f..b927f92ea 100644 --- a/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/service/sku/bo/ProductSkuBO.java +++ b/product-service-project/product-service-app/src/main/java/cn/iocoder/mall/productservice/service/sku/bo/ProductSkuBO.java @@ -1,10 +1,10 @@ package cn.iocoder.mall.productservice.service.sku.bo; -import cn.iocoder.mall.productservice.dal.mysql.dataobject.attr.ProductAttrValueDO; import lombok.Data; import lombok.experimental.Accessors; import java.util.Date; +import java.util.List; /** * 商品 SKU BO @@ -33,11 +33,9 @@ public class ProductSkuBO { */ private String picUrl; /** - * 规格值({@link ProductAttrValueDO})数组 - * - * 数组,以逗号分隔 + * 规格值编号数组 */ - private String attrs; + private List attrValueIds; /** * 价格,单位:分 */ diff --git a/product/product-start/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductAttrController.java b/product/product-start/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductAttrController.java index 8e0b2c6d4..425db2b6f 100644 --- a/product/product-start/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductAttrController.java +++ b/product/product-start/src/main/java/cn/iocoder/mall/product/application/controller/admins/AdminsProductAttrController.java @@ -32,19 +32,6 @@ public class AdminsProductAttrController { @Reference(validation = "true", version = "${dubbo.provider.ProductAttrService.version}") private ProductAttrService productAttrService; - @GetMapping("/attr/page") - @ApiOperation("获得规格分页") - public CommonResult attrPage(@RequestParam(value = "name", required = false) String name, - @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, - @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) { - // 创建 ProductAttrPageDTO 对象 - ProductAttrPageDTO productAttrPageDTO = new ProductAttrPageDTO().setName(name).setPageNo(pageNo).setPageSize(pageSize); - // 查询分页 - ProductAttrPageBO result = productAttrService.getProductAttrPage(productAttrPageDTO); - // 返回结果 - return success(ProductAttrConvert.INSTANCE.convert2(result)); - } - @GetMapping("/attr/tree") @ApiOperation(value = "获得规格树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。") public CommonResult> tree() { @@ -54,87 +41,4 @@ public class AdminsProductAttrController { return success(ProductAttrConvert.INSTANCE.convert(result)); } - @PostMapping("/attr/add") - @ApiOperation(value = "创建商品规格") - @ApiImplicitParams({ - @ApiImplicitParam(name = "name", value = "规格名", required = true, example = "颜色") - }) - public CommonResult addAttr(@RequestParam("name") String name) { - // 创建 ProductAttrAddDTO 对象 - ProductAttrAddDTO productAttrAddDTO = new ProductAttrAddDTO().setName(name); - // 添加 - ProductAttrBO result = productAttrService.addProductAttr(AdminSecurityContextHolder.getContext().getAdminId(), productAttrAddDTO); - // 返回结果 - return success(ProductAttrConvert.INSTANCE.convert3(result)); - } - - @PostMapping("/attr/update") - @ApiOperation(value = "修改商品规格") - @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "规格编号", required = true, example = "1"), - @ApiImplicitParam(name = "name", value = "规格名", required = true, example = "颜色") - }) - public CommonResult updateAttr(@RequestParam("id") Integer id, - @RequestParam("name") String name) { - // 创建 ProductAttrUpdateDTO 对象 - ProductAttrUpdateDTO productAttrUpdateDTO = new ProductAttrUpdateDTO().setId(id).setName(name); - // 更新 - return success(productAttrService.updateProductAttr(AdminSecurityContextHolder.getContext().getAdminId(), productAttrUpdateDTO)); - } - - @PostMapping("/attr/update_status") - @ApiOperation(value = "修改商品规格状态") - @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "规格编号", required = true, example = "100"), - @ApiImplicitParam(name = "status", value = "状态", required = true, example = "1") - }) - public CommonResult updateAttrStatus(@RequestParam("id") Integer id, - @RequestParam("status") Integer status) { - return success(productAttrService.updateProductAttrStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status)); - } - - // TODO 芋艿 暂时不考虑 delete Attr 。因为关联逻辑比较多 - - @PostMapping("/attr_value/add") - @ApiOperation(value = "创建商品规格值") - @ApiImplicitParams({ - @ApiImplicitParam(name = "attrId", value = "规格编号", required = true, example = "100"), - @ApiImplicitParam(name = "name", value = "规格值", required = true, example = "蓝色") - }) - public CommonResult addAttrValue(@RequestParam("attrId") Integer attrId, - @RequestParam("name") String name) { - // 创建 ProductAttrValueAddDTO 对象 - ProductAttrValueAddDTO productAttrValueAddDTO = new ProductAttrValueAddDTO().setAttrId(attrId).setName(name); - // 添加 - ProductAttrValueBO result = productAttrService.addProductAttrValue(AdminSecurityContextHolder.getContext().getAdminId(), productAttrValueAddDTO); - // 返回结果 - return success(ProductAttrConvert.INSTANCE.convert4(result)); - } - - @PostMapping("/attr_value/update") - @ApiOperation(value = "修改商品规格值") - @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "规格值编号", required = true, example = "100"), - @ApiImplicitParam(name = "name", value = "规格值", required = true, example = "蓝色") - }) - public CommonResult updateAttrValue(@RequestParam("id") Integer id, - @RequestParam("name") String name) { - // 创建 ProductAttrValueUpdateDTO 对象 - ProductAttrValueUpdateDTO productAttrValueUpdateDTO = new ProductAttrValueUpdateDTO().setId(id).setName(name); - // 更新 - return success(productAttrService.updateProductAttrValue(AdminSecurityContextHolder.getContext().getAdminId(), productAttrValueUpdateDTO)); - } - - @PostMapping("/attr_value/update_status") - @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "规格编号", required = true, example = "100"), - @ApiImplicitParam(name = "status", value = "状态", required = true, example = "1") - }) - public CommonResult updateAttrValueStatus(@RequestParam("id") Integer id, - @RequestParam("status") Integer status) { - return success(productAttrService.updateProductAttrValueStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status)); - } - - // TODO 芋艿 暂时不考虑 delete Attr Value 。因为关联逻辑比较多 - } diff --git a/search-service-project/search-service-api/src/main/java/cn/iocoder/mall/searchservice/rpc/package-info.java b/search-service-project/search-service-api/src/main/java/cn/iocoder/mall/searchservice/rpc/package-info.java new file mode 100644 index 000000000..1daa4587e --- /dev/null +++ b/search-service-project/search-service-api/src/main/java/cn/iocoder/mall/searchservice/rpc/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.mall.searchservice.rpc; diff --git a/search-service-project/search-service-api/src/main/java/cn/iocoder/mall/searchservice/rpc/product/SearchProductRpc.java b/search-service-project/search-service-api/src/main/java/cn/iocoder/mall/searchservice/rpc/product/SearchProductRpc.java new file mode 100644 index 000000000..478927989 --- /dev/null +++ b/search-service-project/search-service-api/src/main/java/cn/iocoder/mall/searchservice/rpc/product/SearchProductRpc.java @@ -0,0 +1,7 @@ +package cn.iocoder.mall.searchservice.rpc.product; + +/** + * 商品搜索 RPC 接口 + */ +public interface SearchProductRpc { +} diff --git a/search-service-project/search-service-app/pom.xml b/search-service-project/search-service-app/pom.xml index 5020ba6b2..c9ffabefb 100644 --- a/search-service-project/search-service-app/pom.xml +++ b/search-service-project/search-service-app/pom.xml @@ -32,6 +32,13 @@ 1.0-SNAPSHOT + + + cn.iocoder.mall + search-service-api + 1.0-SNAPSHOT + + cn.iocoder.mall diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/SearchServiceApplication.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/SearchServiceApplication.java index 257bf5668..96016368b 100644 --- a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/SearchServiceApplication.java +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/SearchServiceApplication.java @@ -1,4 +1,15 @@ package cn.iocoder.mall.searchservice; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication public class SearchServiceApplication { + + public static void main(String[] args) { + // 解决 ES java.lang.IllegalStateException: availableProcessors is already + System.setProperty("es.set.netty.runtime.available.processors", "false"); + SpringApplication.run(SearchServiceApplication.class, args); + } + } diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/convert/package-info.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/convert/package-info.java new file mode 100644 index 000000000..fdea95c78 --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/convert/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.mall.searchservice.convert; diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/convert/product/SearchProductConvert.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/convert/product/SearchProductConvert.java new file mode 100644 index 000000000..87dea27a7 --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/convert/product/SearchProductConvert.java @@ -0,0 +1,30 @@ +package cn.iocoder.mall.searchservice.convert.product; + +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 org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SearchProductConvert { + + SearchProductConvert INSTANCE = Mappers.getMapper(SearchProductConvert.class); + + + @Mapping(source = "spu.id", target = "id") + @Mapping(source = "spu.name", target = "name") + @Mapping(source = "spu.sellPoint", target = "sellPoint") + @Mapping(source = "spu.description", target = "description") + @Mapping(source = "spu.cid", target = "cid") + @Mapping(source = "category.name", target = "categoryName") + @Mapping(source = "spu.picUrls", target = "picUrls") + @Mapping(source = "spu.visible", target = "visible") + @Mapping(source = "spu.sort", target = "sort") + SearchProductCreateBO convert(ProductSpuRespDTO spu, ProductCategoryRespDTO category); + + ESProductDO convert(SearchProductCreateBO bean); + +} diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/dal/es/repository/ProductRepository.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/dal/es/repository/ESProductRepository.java similarity index 97% rename from search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/dal/es/repository/ProductRepository.java rename to search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/dal/es/repository/ESProductRepository.java index 8a630ad17..ca32ac9c7 100644 --- a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/dal/es/repository/ProductRepository.java +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/dal/es/repository/ESProductRepository.java @@ -21,7 +21,7 @@ import java.util.List; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; @Repository -public interface ProductRepository extends ElasticsearchRepository { +public interface ESProductRepository extends ElasticsearchRepository { @Deprecated ESProductDO findByName(String name); diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/manager/product/ProductSearchManager.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/manager/product/ProductSearchManager.java deleted file mode 100644 index aa0084e06..000000000 --- a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/manager/product/ProductSearchManager.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.mall.searchservice.manager.product; - -import cn.iocoder.common.framework.vo.CommonResult; -import cn.iocoder.mall.productservice.rpc.category.ProductCategoryRpc; -import cn.iocoder.mall.productservice.rpc.sku.ProductSkuRpc; -import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO; -import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO; -import cn.iocoder.mall.productservice.rpc.spu.ProductSpuRpc; -import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuRespDTO; -import org.apache.dubbo.config.annotation.DubboReference; -import org.springframework.stereotype.Service; - -import java.util.List; - -@Service -public class ProductSearchManager { - - @DubboReference(version = "${dubbo.consumer.ProductSpuRpc.version}") - private ProductSpuRpc productSpuRpc; - @DubboReference(version = "${dubbo.consumer.ProductSkuRpc.version}") - private ProductSkuRpc productSkuRpc; - @DubboReference(version = "${dubbo.consumer.ProductCategoryRpc.version}") - private ProductCategoryRpc productCategoryRpc; - -// @DubboReference( version = "${dubbo.consumer.CartService.version}") -// private CartService cartService; - - public Boolean saveProduct(Integer id) { - // 获得商品 SPU - CommonResult productSpuResult = productSpuRpc.getProductSpu(id); - productSpuResult.checkError(); - // 获得商品 SKU - CommonResult> listProductSkusResult = - productSkuRpc.listProductSkus(new ProductSkuListQueryReqDTO().setProductSpuId(id)); - listProductSkusResult.checkError(); - - return true; - } - -} diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/manager/product/SearchProductManager.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/manager/product/SearchProductManager.java new file mode 100644 index 000000000..6fd284910 --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/manager/product/SearchProductManager.java @@ -0,0 +1,79 @@ +package cn.iocoder.mall.searchservice.manager.product; + +import cn.iocoder.common.framework.util.CollectionUtils; +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.productservice.rpc.category.ProductCategoryRpc; +import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO; +import cn.iocoder.mall.productservice.rpc.sku.ProductSkuRpc; +import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO; +import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO; +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 lombok.extern.slf4j.Slf4j; +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; + +@Service +@Slf4j +public class SearchProductManager { + + @DubboReference(version = "${dubbo.consumer.ProductSpuRpc.version}") + private ProductSpuRpc productSpuRpc; + @DubboReference(version = "${dubbo.consumer.ProductSkuRpc.version}") + private ProductSkuRpc productSkuRpc; + @DubboReference(version = "${dubbo.consumer.ProductCategoryRpc.version}") + private ProductCategoryRpc productCategoryRpc; + +// @DubboReference( version = "${dubbo.consumer.CartService.version}") +// private CartService cartService; + + @Autowired + private SearchProductService searchProductService; + + public Boolean saveProduct(Integer id) { + // 获得商品 SPU + CommonResult productSpuResult = productSpuRpc.getProductSpu(id); + productSpuResult.checkError(); + if (productSpuResult.getData() == null) { + log.error("[saveProduct][商品 SPU({}) 不存在]", id); + return false; + } + // 获得商品 SKU + CommonResult> listProductSkusResult = + productSkuRpc.listProductSkus(new ProductSkuListQueryReqDTO().setProductSpuId(id)); + listProductSkusResult.checkError(); + if (CollectionUtils.isEmpty(listProductSkusResult.getData())) { + log.error("[saveProduct][商品 SPU({}) 的 SKU 不存在]", id); + return false; + } + // 获得商品分类 + CommonResult getProductCategoryResult = + productCategoryRpc.getProductCategory(productSpuResult.getData().getCid()); + getProductCategoryResult.checkError(); + if (getProductCategoryResult.getData() == null) { + log.error("[saveProduct][商品 SPU({}) 的分类({}) 不存在]", id, productSpuResult.getData().getCid()); + return false; + } + // 保存商品到 ES 中 + SearchProductCreateBO searchProductCreateBO = SearchProductConvert.INSTANCE.convert( + productSpuResult.getData(), getProductCategoryResult.getData()); + ProductSkuRespDTO productSku = listProductSkusResult.getData().stream() + .min(Comparator.comparing(ProductSkuRespDTO::getPrice)).orElse(null); + assert productSku != null; +// // 价格计算 TODO 芋艿:需要补充,暂时使用这个逻辑 +// CalcSkuPriceBO calSkuPriceResult = cartService.calcSkuPrice(sku.getId()); + searchProductCreateBO.setOriginalPrice(productSku.getPrice()); + searchProductCreateBO.setBuyPrice(productSku.getPrice()); + searchProductCreateBO.setQuantity(productSku.getQuantity()); + searchProductService.createSearchProduct(searchProductCreateBO); + return true; + } + +} diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/mq/consumer/PayTransactionPaySuccessConsumer.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/mq/consumer/PayTransactionPaySuccessConsumer.java new file mode 100644 index 000000000..0ec04e640 --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/mq/consumer/PayTransactionPaySuccessConsumer.java @@ -0,0 +1,27 @@ +package cn.iocoder.mall.searchservice.mq.consumer; + +import cn.iocoder.mall.searchservice.manager.product.SearchProductManager; +import cn.iocoder.mall.searchservice.mq.consumer.message.ProductUpdateMessage; +import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; +import org.apache.rocketmq.spring.core.RocketMQListener; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.Assert; + +@Service +@RocketMQMessageListener( + topic = ProductUpdateMessage.TOPIC, + consumerGroup = "${spring.application.name}-consumer-group-" + ProductUpdateMessage.TOPIC +) +public class PayTransactionPaySuccessConsumer implements RocketMQListener { + + @Autowired + private SearchProductManager productSearchManager; + + @Override + public void onMessage(ProductUpdateMessage message) { + Boolean result = productSearchManager.saveProduct(message.getId()); + Assert.isTrue(result, String.format("重构商品(%d)的 ES 索引,必然成功。实际结果是 %s", message.getId(), result)); + } + +} diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/mq/consumer/message/ProductUpdateMessage.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/mq/consumer/message/ProductUpdateMessage.java new file mode 100644 index 000000000..03d956c55 --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/mq/consumer/message/ProductUpdateMessage.java @@ -0,0 +1,20 @@ +package cn.iocoder.mall.searchservice.mq.consumer.message; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 商品更新(包括创建)消息 + */ +@Data +@Accessors(chain = true) +public class ProductUpdateMessage { + + public static final String TOPIC = "ProductUpdate"; + + /** + * 商品编号 + */ + private Integer id; + +} diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/rpc/package-info.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/rpc/package-info.java new file mode 100644 index 000000000..1daa4587e --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/rpc/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.mall.searchservice.rpc; diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/rpc/product/SearchProductRpcImpl.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/rpc/product/SearchProductRpcImpl.java new file mode 100644 index 000000000..6339764ba --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/rpc/product/SearchProductRpcImpl.java @@ -0,0 +1,7 @@ +package cn.iocoder.mall.searchservice.rpc.product; + +import org.apache.dubbo.config.annotation.DubboService; + +@DubboService +public class SearchProductRpcImpl implements SearchProductRpc { +} diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/ProductSearchService.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/ProductSearchService.java deleted file mode 100644 index 40fab0a6d..000000000 --- a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/ProductSearchService.java +++ /dev/null @@ -1,7 +0,0 @@ -package cn.iocoder.mall.searchservice.service.product; - -import org.springframework.stereotype.Service; - -@Service -public class ProductSearchService { -} diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/SearchProductService.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/SearchProductService.java new file mode 100644 index 000000000..8505ccded --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/SearchProductService.java @@ -0,0 +1,21 @@ +package cn.iocoder.mall.searchservice.service.product; + +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 org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class SearchProductService { + + @Autowired + private ESProductRepository productRepository; + + public void createSearchProduct(SearchProductCreateBO createBO) { + ESProductDO productDO = SearchProductConvert.INSTANCE.convert(createBO); + productRepository.save(productDO); + } + +} diff --git a/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/bo/SearchProductCreateBO.java b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/bo/SearchProductCreateBO.java new file mode 100644 index 000000000..8512baeb2 --- /dev/null +++ b/search-service-project/search-service-app/src/main/java/cn/iocoder/mall/searchservice/service/product/bo/SearchProductCreateBO.java @@ -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 +public class SearchProductCreateBO { + + private Integer id; + + // ========== 基本信息 ========= + /** + * SPU 名字 + */ + private String name; + /** + * 卖点 + */ + private String sellPoint; + /** + * 描述 + */ + private String description; + /** + * 分类编号 + */ + private Integer cid; + /** + * 分类名 + */ + private String categoryName; + /** + * 商品主图地数组 + */ + private List 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; + +} diff --git a/search-service-project/search-service-app/src/main/resources/application.yaml b/search-service-project/search-service-app/src/main/resources/application.yaml index cb31e8c15..b107c5938 100644 --- a/search-service-project/search-service-app/src/main/resources/application.yaml +++ b/search-service-project/search-service-app/src/main/resources/application.yaml @@ -5,6 +5,16 @@ spring: # Profile 的配置项 profiles: active: local + # Elasticsearch 配置项 + data: + elasticsearch: + cluster-name: elasticsearch + cluster-nodes: 400-infra.server.iocoder.cn:9300 + repositories: + enable: true + elasticsearch: + rest: + uris: 400-infra.server.iocoder.cn:9200 # Dubbo 配置项 dubbo: @@ -17,7 +27,7 @@ dubbo: port: -1 # Dubbo 提供服务的扫描基础包 scan: - base-packages: cn.iocoder.mall.searrchservice.rpc + base-packages: cn.iocoder.mall.searchservice.rpc # Dubbo 服务提供者的配置 provider: filter: -exception @@ -31,16 +41,16 @@ dubbo: version: 1.0.0 ProductSpuRpc: version: 1.0.0 + ProductSkuRpc: + version: 1.0.0 # RocketMQ 配置项 rocketmq: name-server: 400-infra.server.iocoder.cn:9876 - producer: - group: ${spring.application.name}-producer-group # Mall 配置项 mall: # 错误码配置项对应 ErrorCodeProperties 配置类 error-code: group: ${spring.application.name} - constants-class: cn.iocoder.mall.searrchservice.enums.ProductErrorCodeConstants + constants-class: cn.iocoder.mall.searchservice.enums.ProductErrorCodeConstants diff --git a/search/search-application/pom.xml b/search/search-application/pom.xml deleted file mode 100644 index 0e839c136..000000000 --- a/search/search-application/pom.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - search - cn.iocoder.mall - 1.0-SNAPSHOT - - 4.0.0 - - search-application - - - - - cn.iocoder.mall - search-rest - 1.0-SNAPSHOT - - - cn.iocoder.mall - search-rpc - 1.0-SNAPSHOT - - - - - diff --git a/search/search-application/src/main/java/cn/iocoder/mall/search/application/SearchApplication.java b/search/search-application/src/main/java/cn/iocoder/mall/search/application/SearchApplication.java deleted file mode 100644 index 1f1257971..000000000 --- a/search/search-application/src/main/java/cn/iocoder/mall/search/application/SearchApplication.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.mall.search.application; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.context.config.ConfigFileApplicationListener; -import org.springframework.scheduling.annotation.EnableAsync; - -@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.search"}) -@EnableAsync(proxyTargetClass = true) -public class SearchApplication { - /** - * 设置需要读取的配置文件的名字。 - * 基于 {@link org.springframework.boot.context.config.ConfigFileApplicationListener#CONFIG_NAME_PROPERTY} 实现。 - */ - private static final String CONFIG_NAME_VALUE = "biz,rest,rpc,application"; - public static void main(String[] args) { - - // 设置环境变量 - System.setProperty(ConfigFileApplicationListener.CONFIG_NAME_PROPERTY, CONFIG_NAME_VALUE); - - // 解决 ES java.lang.IllegalStateException: availableProcessors is already - System.setProperty("es.set.netty.runtime.available.processors", "false"); - SpringApplication.run(SearchApplication.class, args); - } - -} diff --git a/search/search-application/src/main/resources/application-test.yaml b/search/search-application/src/main/resources/application-test.yaml deleted file mode 100644 index e3581327f..000000000 --- a/search/search-application/src/main/resources/application-test.yaml +++ /dev/null @@ -1,6 +0,0 @@ -swagger: - enable: true - title: 搜索子系统 - description: 搜索子系统 - version: 1.0.0 - base-package: cn.iocoder.mall.search.application.controller diff --git a/search/search-application/src/main/resources/application.yaml b/search/search-application/src/main/resources/application.yaml deleted file mode 100644 index 4ddc8d284..000000000 --- a/search/search-application/src/main/resources/application.yaml +++ /dev/null @@ -1,6 +0,0 @@ -spring: - application: - name: search-application - # Profile 的配置项 - profiles: - active: local diff --git a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java deleted file mode 100644 index d2b3156e2..000000000 --- a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/mq/PayTransactionPaySuccessConsumer.java +++ /dev/null @@ -1,27 +0,0 @@ -package cn.iocoder.mall.search.biz.mq; - -import cn.iocoder.mall.product.api.message.ProductUpdateMessage; -import cn.iocoder.mall.search.biz.ProductSearchService; -import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; -import org.apache.rocketmq.spring.core.RocketMQListener; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.util.Assert; - -@Service -@RocketMQMessageListener( - topic = ProductUpdateMessage.TOPIC, - consumerGroup = "search-consumer-group-" + ProductUpdateMessage.TOPIC -) -public class PayTransactionPaySuccessConsumer implements RocketMQListener { - - @Autowired - private ProductSearchService productSearchService; - - @Override - public void onMessage(ProductUpdateMessage message) { - Boolean result = productSearchService.save(message.getId()); - Assert.isTrue(result, String.format("重构商品 ES 索引,必然成功。实际结果是 %s", result)); - } - -} diff --git a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java index 1b3be0fe3..73dbce49a 100644 --- a/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java +++ b/search/search-service-impl/src/main/java/cn/iocoder/mall/search/biz/service/ProductSearchServiceImpl.java @@ -68,27 +68,6 @@ public class ProductSearchServiceImpl implements ProductSearchService { return rebuildCounts; } - @Override - public Boolean save(Integer id) { - // 获得商品性情 - ProductSpuDetailBO result = productSpuService.getProductSpuDetail(id); - // 存储到 ES 中 - ESProductDO product = convert(result); - productRepository.save(product); - // 返回成功 - return true; - } - - @SuppressWarnings("OptionalGetWithoutIsPresent") - private ESProductDO convert(ProductSpuDetailBO spu) { - // 获得最小价格的 SKU ,用于下面的价格计算 - ProductSpuDetailBO.Sku sku = spu.getSkus().stream().min(Comparator.comparing(ProductSpuDetailBO.Sku::getPrice)).get(); - // 价格计算 - CalcSkuPriceBO calSkuPriceResult = cartService.calcSkuPrice(sku.getId()); - // 拼装结果 - return ProductSearchConvert.INSTANCE.convert(spu, calSkuPriceResult); - } - @Override public ProductPageBO getSearchPage(ProductSearchPageDTO searchPageDTO) { checkSortFieldInvalid(searchPageDTO.getSorts());