完成的商品搜索和条件功能
This commit is contained in:
@@ -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
|
||||
|
||||
###
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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 芋艿:等做到促销在处理
|
||||
// 目前只促销单体商品促销,目前仅限制折扣。
|
||||
/**
|
||||
* 促销活动编号
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user