完成的商品搜索和条件功能

This commit is contained in:
YunaiV
2020-08-04 19:42:54 +08:00
parent f3316d14c7
commit b83262af5f
240 changed files with 246 additions and 859 deletions

View File

@@ -0,0 +1,9 @@
### /product-spu/page 成功(全部)
GET {{shop-api-base-url}}/product-spu/page?pageNo=1&pageSize=10&keyword=骚气
Content-Type: application/x-www-form-urlencoded
### /product-spu/search-condition 成功
GET {{shop-api-base-url}}/product-spu/search-condition?keyword=骚气
Content-Type: application/x-www-form-urlencoded
###

View File

@@ -4,13 +4,16 @@ import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuPageReqVO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuRespVO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuSearchConditionRespVO;
import cn.iocoder.mall.shopweb.manager.product.ProductSpuManager;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import static cn.iocoder.common.framework.vo.CommonResult.success;
@@ -30,4 +33,12 @@ public class ProductSpuController {
return success(productSpuManager.pageProductSpu(pageReqVO));
}
@GetMapping("/search-condition")
@ApiOperation("获得商品的搜索条件")
@ApiImplicitParam(name = "keyword", value = "关键字", example = "芋艿")
public CommonResult<ProductSpuSearchConditionRespVO> getProductSpuSearchCondition(
@RequestParam(value = "keyword", required = false) String keyword) {
return success(productSpuManager.getProductSpuSearchCondition(keyword));
}
}

View File

@@ -1,24 +1,25 @@
package cn.iocoder.mall.shopweb.controller.product.vo.product;
import cn.iocoder.common.framework.vo.PageParam;
import cn.iocoder.common.framework.vo.SortingField;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@ApiModel("商品 SPU 分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class ProductSpuPageReqVO extends PageParam {
/**
* 分类编号
*/
@ApiModelProperty(value = "分类编号", example = "1")
private Integer cid;
/**
* 关键字
*/
@ApiModelProperty(value = "关键字", example = "芋艿")
private String keyword;
/**
* 排序字段数组
*/
private List<SortingField> sorts;
@ApiModelProperty(value = "排序字段", example = "buyPrice", notes = "参见 SearchProductPageQuerySortFieldEnum 枚举")
private String sortField;
@ApiModelProperty(value = "排序顺序", example = "1")
private String sortOrder;
}

View File

@@ -1,6 +1,7 @@
package cn.iocoder.mall.shopweb.controller.product.vo.product;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -11,62 +12,38 @@ import java.util.List;
@Accessors(chain = true)
public class ProductSpuRespVO {
@ApiModelProperty(value = "SPU 编号", required = true)
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
@ApiModelProperty(value = "SPU 名字", required = true, example = "芋艿")
private String name;
/**
* 卖点
*/
@ApiModelProperty(value = "卖点", required = true, example = "好吃好玩")
private String sellPoint;
/**
* 描述
*/
@ApiModelProperty(value = "描述", required = true, example = "我是哈哈哈")
private String description;
/**
* 分类编号
*/
@ApiModelProperty(value = "分类编号", required = true, example = "1")
private Integer cid;
/**
* 分类名
*/
@ApiModelProperty(value = "分类名字", required = true, example = "蔬菜")
private String categoryName;
/**
* 商品主图地数组
*/
@ApiModelProperty(value = "商品主图地址", required = true, example = "http://www.iocoder.cn/xxx.jpg", notes = "多个之间,使用逗号分隔")
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
@ApiModelProperty(value = "是否上架商品", required = true, example = "true")
private Boolean visible;
/**
* 排序字段
*/
@ApiModelProperty(value = "排序字段", required = true, example = "1024")
private Integer sort;
// ========== Sku 相关字段 =========
/**
* 原价格,单位:分
*/
@ApiModelProperty(value = "原始价格,单位:分", required = true, example = "233", notes = "该价格为商品的原始价格")
private Integer originalPrice;
/**
* 购买价格,单位:分。
*/
@ApiModelProperty(value = "购买价格,单位:分", required = true, example = "233", notes = "该价格为商品经过优惠计算后的价格")
private Integer buyPrice;
/**
* 库存数量
*/
@ApiModelProperty(value = "库存数量", required = true, example = "1024")
private Integer quantity;
// ========== 促销活动相关字段 =========
// ========== 促销活动相关字段 ========= TODO 芋艿:等做到促销在处理
// 目前只促销单体商品促销,目前仅限制折扣。
/**
* 促销活动编号

View File

@@ -0,0 +1,32 @@
package cn.iocoder.mall.shopweb.controller.product.vo.product;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@ApiModel("商品 SPU 搜索条件 Response VO")
@Data
@Accessors(chain = true)
public class ProductSpuSearchConditionRespVO {
@ApiModel("商品分类信息")
@Data
@Accessors(chain = true)
public static class Category {
@ApiModelProperty(value = "分类编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "分类名称", required = true, example = "手机")
private String name;
}
/**
* 商品分类数组
*/
private List<Category> categories;
}

View File

@@ -1,20 +1,37 @@
package cn.iocoder.mall.shopweb.convert.product;
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.productservice.rpc.category.dto.ProductCategoryRespDTO;
import cn.iocoder.mall.searchservice.rpc.product.dto.SearchProductPageReqDTO;
import cn.iocoder.mall.searchservice.rpc.product.dto.SearchProductRespDTO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuPageReqVO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuRespVO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuSearchConditionRespVO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.Collections;
import java.util.List;
@Mapper
public interface ProductSpuConvert {
ProductSpuConvert INSTANCE = Mappers.getMapper(ProductSpuConvert.class);
SearchProductPageReqDTO convert(ProductSpuPageReqVO bean);
default SearchProductPageReqDTO convert(ProductSpuPageReqVO bean) {
SearchProductPageReqDTO reqDTO = new SearchProductPageReqDTO()
.setCid(bean.getCid()).setKeyword(bean.getKeyword());
reqDTO.setPageNo(bean.getPageNo()).setPageSize(bean.getPageSize());
if (StringUtils.hasText(bean.getSortField()) && StringUtils.hasText(bean.getSortOrder())) {
reqDTO.setSorts(Collections.singletonList(new SortingField(bean.getSortField(), bean.getSortOrder())));
}
return reqDTO;
}
PageResult<ProductSpuRespVO> convertPage(PageResult<SearchProductRespDTO> page);
List<ProductSpuSearchConditionRespVO.Category> convertList(List<ProductCategoryRespDTO> list);
}

View File

@@ -1,18 +1,28 @@
package cn.iocoder.mall.shopweb.manager.product;
import cn.iocoder.common.framework.util.CollectionUtils;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.productservice.rpc.category.ProductCategoryRpc;
import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO;
import cn.iocoder.mall.searchservice.enums.product.SearchProductConditionFieldEnum;
import cn.iocoder.mall.searchservice.rpc.product.SearchProductRpc;
import cn.iocoder.mall.searchservice.rpc.product.dto.SearchProductConditionReqDTO;
import cn.iocoder.mall.searchservice.rpc.product.dto.SearchProductConditionRespDTO;
import cn.iocoder.mall.searchservice.rpc.product.dto.SearchProductRespDTO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuPageReqVO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuRespVO;
import cn.iocoder.mall.shopweb.controller.product.vo.product.ProductSpuSearchConditionRespVO;
import cn.iocoder.mall.shopweb.convert.product.ProductSpuConvert;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.Collections;
import java.util.List;
/**
* Product SPU Manager
* 商品 SPU Manager
*/
@Service
@Validated
@@ -21,6 +31,9 @@ public class ProductSpuManager {
@DubboReference(version = "${dubbo.consumer.SearchProductRpc.version}")
private SearchProductRpc searchProductRpc;
@DubboReference(version = "${dubbo.consumer.ProductCategoryRpc.version}")
private ProductCategoryRpc productCategoryRpc;
public PageResult<ProductSpuRespVO> pageProductSpu(ProductSpuPageReqVO pageReqVO) {
CommonResult<PageResult<SearchProductRespDTO>> pageResult =
searchProductRpc.pageSearchProduct(ProductSpuConvert.INSTANCE.convert(pageReqVO));
@@ -28,4 +41,23 @@ public class ProductSpuManager {
return ProductSpuConvert.INSTANCE.convertPage(pageResult.getData());
}
public ProductSpuSearchConditionRespVO getProductSpuSearchCondition(String keyword) {
// 获得搜索条件
CommonResult<SearchProductConditionRespDTO> getSearchProductConditionResult =
searchProductRpc.getSearchProductCondition(new SearchProductConditionReqDTO().setKeyword(keyword)
.setFields(Collections.singletonList(SearchProductConditionFieldEnum.CATEGORY.getField())));
getSearchProductConditionResult.checkError();
// 拼接结果
ProductSpuSearchConditionRespVO conditionRespVO = new ProductSpuSearchConditionRespVO();
if (CollectionUtils.isEmpty(getSearchProductConditionResult.getData().getCids())) {
conditionRespVO.setCategories(Collections.emptyList());
} else {
CommonResult<List<ProductCategoryRespDTO>> listProductCategoriesResult =
productCategoryRpc.listProductCategories(getSearchProductConditionResult.getData().getCids());
listProductCategoriesResult.checkError();
conditionRespVO.setCategories(ProductSpuConvert.INSTANCE.convertList(listProductCategoriesResult.getData()));
}
return conditionRespVO;
}
}