后端:尝试引入 ES 服务
This commit is contained in:
parent
6fdec47430
commit
7fcb9da38e
@ -100,7 +100,7 @@ const serviceRouter = function(requestUrl) {
|
|||||||
|
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
// baseURL: baseUrl, // api 的 base_url
|
// baseURL: baseUrl, // api 的 base_url
|
||||||
timeout: 5000, // request timeout
|
timeout: 30000, // request timeout
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public interface OrderService {
|
|||||||
* @param orderDelivery
|
* @param orderDelivery
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
CommonResult orderDelivery(OrderDeliveryDTO orderDelivery);
|
CommonResult<OrderRecipientBO> orderDelivery(OrderDeliveryDTO orderDelivery);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新订单 - 备注
|
* 更新订单 - 备注
|
||||||
@ -133,14 +133,6 @@ public interface OrderService {
|
|||||||
*/
|
*/
|
||||||
CommonResult deleteOrder(Integer id);
|
CommonResult deleteOrder(Integer id);
|
||||||
|
|
||||||
/**
|
|
||||||
* 监听支付动作
|
|
||||||
*
|
|
||||||
* mq 更新 payStatus
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
CommonResult listenerPayment();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新订单支付成功
|
* 更新订单支付成功
|
||||||
*
|
*
|
||||||
|
@ -16,7 +16,7 @@ public class CalcSkuPriceBO {
|
|||||||
*/
|
*/
|
||||||
private PromotionActivityBO fullPrivilege;
|
private PromotionActivityBO fullPrivilege;
|
||||||
/**
|
/**
|
||||||
* 电视和折扣促销活动
|
* 限时折扣促销活动
|
||||||
*/
|
*/
|
||||||
private PromotionActivityBO timeLimitedDiscount;
|
private PromotionActivityBO timeLimitedDiscount;
|
||||||
/**
|
/**
|
||||||
|
@ -20,12 +20,13 @@ public class OrderDeliveryDTO implements Serializable {
|
|||||||
* 订单id
|
* 订单id
|
||||||
*/
|
*/
|
||||||
private Integer orderId;
|
private Integer orderId;
|
||||||
|
// TODO 芋艿,物流方式。会存在无需物流的情况
|
||||||
/**
|
/**
|
||||||
* 物流 (字典)
|
* 物流公司 (字典)
|
||||||
*/
|
*/
|
||||||
private Integer logistics;
|
private Integer logistics;
|
||||||
/**
|
/**
|
||||||
* 物流编号
|
* 物流单编号
|
||||||
*/
|
*/
|
||||||
private String logisticsNo;
|
private String logisticsNo;
|
||||||
|
|
||||||
@ -36,4 +37,5 @@ public class OrderDeliveryDTO implements Serializable {
|
|||||||
* 订单 orderItemId
|
* 订单 orderItemId
|
||||||
*/
|
*/
|
||||||
private List<Integer> orderItemIds;
|
private List<Integer> orderItemIds;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,4 +34,5 @@ public class OrderLogisticsDetailDO extends DeletableDO {
|
|||||||
* 物流信息
|
* 物流信息
|
||||||
*/
|
*/
|
||||||
private String logisticsInformation;
|
private String logisticsInformation;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -198,8 +198,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
List<OrderItemDO> orderItemDOList = OrderItemConvert.INSTANCE.convert(orderItemDTOList);
|
List<OrderItemDO> orderItemDOList = OrderItemConvert.INSTANCE.convert(orderItemDTOList);
|
||||||
|
|
||||||
// 获取商品信息
|
// 获取商品信息
|
||||||
Set<Integer> skuIds = orderItemDOList.stream()
|
Set<Integer> skuIds = orderItemDOList.stream().map(OrderItemDO::getSkuId).collect(Collectors.toSet());
|
||||||
.map(orderItemDO -> orderItemDO.getSkuId()).collect(Collectors.toSet());
|
|
||||||
CommonResult<List<ProductSkuDetailBO>> productResult = productSpuService.getProductSkuDetailList(skuIds);
|
CommonResult<List<ProductSkuDetailBO>> productResult = productSpuService.getProductSkuDetailList(skuIds);
|
||||||
|
|
||||||
// 校验商品信息
|
// 校验商品信息
|
||||||
@ -273,16 +272,13 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
.setStatus(OrderStatusEnum.WAITING_PAYMENT.getValue())
|
.setStatus(OrderStatusEnum.WAITING_PAYMENT.getValue())
|
||||||
.setHasReturnExchange(OrderHasReturnExchangeEnum.NO.getValue())
|
.setHasReturnExchange(OrderHasReturnExchangeEnum.NO.getValue())
|
||||||
.setRemark(Optional.ofNullable(orderCreateDTO.getRemark()).orElse(""));
|
.setRemark(Optional.ofNullable(orderCreateDTO.getRemark()).orElse(""));
|
||||||
|
|
||||||
orderDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
orderDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||||
orderDO.setCreateTime(new Date());
|
orderDO.setCreateTime(new Date());
|
||||||
orderDO.setUpdateTime(null);
|
orderDO.setUpdateTime(null);
|
||||||
orderMapper.insert(orderDO);
|
orderMapper.insert(orderDO);
|
||||||
|
|
||||||
// 收件人信息
|
// 收件人信息
|
||||||
CommonResult<UserAddressBO> userAddressResult
|
CommonResult<UserAddressBO> userAddressResult = userAddressService.getAddress(userId, orderCreateDTO.getUserAddressId());
|
||||||
= userAddressService.getAddress(userId, orderCreateDTO.getUserAddressId());
|
|
||||||
|
|
||||||
if (userAddressResult.isError()) {
|
if (userAddressResult.isError()) {
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_USER_ADDRESS_FAIL.getCode());
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_GET_USER_ADDRESS_FAIL.getCode());
|
||||||
}
|
}
|
||||||
@ -293,7 +289,6 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
.setType(OrderRecipientTypeEnum.EXPRESS.getValue())
|
.setType(OrderRecipientTypeEnum.EXPRESS.getValue())
|
||||||
.setCreateTime(new Date())
|
.setCreateTime(new Date())
|
||||||
.setUpdateTime(null);
|
.setUpdateTime(null);
|
||||||
|
|
||||||
orderRecipientMapper.insert(orderRecipientDO);
|
orderRecipientMapper.insert(orderRecipientDO);
|
||||||
|
|
||||||
// order item
|
// order item
|
||||||
@ -312,7 +307,6 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
.setCreateTime(new Date())
|
.setCreateTime(new Date())
|
||||||
.setUpdateTime(null);
|
.setUpdateTime(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 一次性插入
|
// 一次性插入
|
||||||
orderItemMapper.insert(orderItemDOList);
|
orderItemMapper.insert(orderItemDOList);
|
||||||
|
|
||||||
@ -367,7 +361,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override // TODO 芋艿,需要确认下这个方法的用途。因为涉及修改价格和数量。
|
||||||
public CommonResult updateOrderItem(OrderItemUpdateDTO orderUpdateDTO) {
|
public CommonResult updateOrderItem(OrderItemUpdateDTO orderUpdateDTO) {
|
||||||
OrderItemDO orderItemDO = OrderItemConvert.INSTANCE.convert(orderUpdateDTO);
|
OrderItemDO orderItemDO = OrderItemConvert.INSTANCE.convert(orderUpdateDTO);
|
||||||
orderItemMapper.updateById(orderItemDO);
|
orderItemMapper.updateById(orderItemDO);
|
||||||
@ -410,7 +404,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional // TODO 芋艿,要校验下 userId 。不然可以取消任何用户的订单列。
|
||||||
public CommonResult cancelOrder(Integer orderId, Integer reason, String otherReason) {
|
public CommonResult cancelOrder(Integer orderId, Integer reason, String otherReason) {
|
||||||
// 关闭订单,在用户还未付款的时候可操作
|
// 关闭订单,在用户还未付款的时候可操作
|
||||||
OrderDO orderDO = orderMapper.selectById(orderId);
|
OrderDO orderDO = orderMapper.selectById(orderId);
|
||||||
@ -451,15 +445,13 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
List<Integer> orderItemIds = orderDelivery.getOrderItemIds();
|
List<Integer> orderItemIds = orderDelivery.getOrderItemIds();
|
||||||
|
|
||||||
// 获取所有订单 items
|
// 获取所有订单 items
|
||||||
List<OrderItemDO> allOrderItems = orderItemMapper
|
List<OrderItemDO> allOrderItems = orderItemMapper.selectByDeletedAndOrderId(orderDelivery.getOrderId(), DeletedStatusEnum.DELETED_NO.getValue());
|
||||||
.selectByDeletedAndOrderId(orderDelivery.getOrderId(), DeletedStatusEnum.DELETED_NO.getValue());
|
|
||||||
|
|
||||||
// 当前需要发货订单,检查 id 和 status
|
// 当前需要发货订单,检查 id 和 status
|
||||||
List<OrderItemDO> needDeliveryOrderItems = allOrderItems.stream()
|
List<OrderItemDO> needDeliveryOrderItems = allOrderItems.stream()
|
||||||
.filter(orderItemDO -> orderItemIds.contains(orderItemDO.getId())
|
.filter(orderItemDO -> orderItemIds.contains(orderItemDO.getId())
|
||||||
&& OrderStatusEnum.WAIT_SHIPMENT.getValue() == orderItemDO.getStatus())
|
&& OrderStatusEnum.WAIT_SHIPMENT.getValue() == orderItemDO.getStatus())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// 发货订单,检查
|
// 发货订单,检查
|
||||||
if (needDeliveryOrderItems.size() != orderItemIds.size()) {
|
if (needDeliveryOrderItems.size() != orderItemIds.size()) {
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_DELIVERY_INCORRECT_DATA.getCode());
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_DELIVERY_INCORRECT_DATA.getCode());
|
||||||
@ -467,14 +459,12 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
|
|
||||||
OrderRecipientDO orderRecipientDO = orderRecipientMapper.selectByOrderId(orderDelivery.getOrderId());
|
OrderRecipientDO orderRecipientDO = orderRecipientMapper.selectByOrderId(orderDelivery.getOrderId());
|
||||||
OrderLogisticsDO orderLogisticsDO = OrderLogisticsConvert.INSTANCE.convert(orderRecipientDO);
|
OrderLogisticsDO orderLogisticsDO = OrderLogisticsConvert.INSTANCE.convert(orderRecipientDO);
|
||||||
|
|
||||||
// 保存物流信息
|
// 保存物流信息
|
||||||
orderLogisticsDO
|
orderLogisticsDO
|
||||||
.setLogisticsNo(orderDelivery.getLogisticsNo())
|
.setLogisticsNo(orderDelivery.getLogisticsNo())
|
||||||
.setLogistics(orderDelivery.getLogistics())
|
.setLogistics(orderDelivery.getLogistics())
|
||||||
.setCreateTime(new Date())
|
.setCreateTime(new Date())
|
||||||
.setUpdateTime(null);
|
.setUpdateTime(null);
|
||||||
|
|
||||||
orderLogisticsMapper.insert(orderLogisticsDO);
|
orderLogisticsMapper.insert(orderLogisticsDO);
|
||||||
|
|
||||||
// 关联订单item 和 物流信息
|
// 关联订单item 和 物流信息
|
||||||
@ -490,7 +480,6 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
.filter(orderItemDO -> OrderStatusEnum.WAIT_SHIPMENT.getValue() == orderItemDO.getStatus()
|
.filter(orderItemDO -> OrderStatusEnum.WAIT_SHIPMENT.getValue() == orderItemDO.getStatus()
|
||||||
&& !orderItemIds.contains(orderItemDO.getId()))
|
&& !orderItemIds.contains(orderItemDO.getId()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
if (unShippedOrderItems.size() <= 0) {
|
if (unShippedOrderItems.size() <= 0) {
|
||||||
orderMapper.updateById(
|
orderMapper.updateById(
|
||||||
new OrderDO()
|
new OrderDO()
|
||||||
@ -498,7 +487,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
.setStatus(OrderStatusEnum.ALREADY_SHIPMENT.getValue())
|
.setStatus(OrderStatusEnum.ALREADY_SHIPMENT.getValue())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 返回成功
|
||||||
return CommonResult.success(null);
|
return CommonResult.success(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,11 +582,6 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
return CommonResult.success(null);
|
return CommonResult.success(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CommonResult listenerPayment() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String updatePaySuccess(String orderId, Integer payAmount) {
|
public String updatePaySuccess(String orderId, Integer payAmount) {
|
||||||
OrderDO order = orderMapper.selectById(Integer.valueOf(orderId));
|
OrderDO order = orderMapper.selectById(Integer.valueOf(orderId));
|
||||||
@ -610,6 +594,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
if (!order.getPresentPrice().equals(payAmount)) { // 支付金额不正确
|
if (!order.getPresentPrice().equals(payAmount)) { // 支付金额不正确
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_PAY_AMOUNT_ERROR.getCode()).getMessage();
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_PAY_AMOUNT_ERROR.getCode()).getMessage();
|
||||||
}
|
}
|
||||||
|
// 更新 OrderDO 状态为已支付,等待发货
|
||||||
OrderDO updateOrderObj = new OrderDO()
|
OrderDO updateOrderObj = new OrderDO()
|
||||||
.setStatus(OrderStatusEnum.WAIT_SHIPMENT.getValue())
|
.setStatus(OrderStatusEnum.WAIT_SHIPMENT.getValue())
|
||||||
.setPayAmount(payAmount)
|
.setPayAmount(payAmount)
|
||||||
@ -618,6 +603,7 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
if (updateCount <= 0) {
|
if (updateCount <= 0) {
|
||||||
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_STATUS_NOT_WAITING_PAYMENT.getCode()).getMessage();
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_STATUS_NOT_WAITING_PAYMENT.getCode()).getMessage();
|
||||||
}
|
}
|
||||||
|
// TODO 芋艿 更新 OrderItemDO
|
||||||
return "success";
|
return "success";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
pom.xml
5
pom.xml
@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>2.1.3.RELEASE</version>
|
<version>2.1.4.RELEASE</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@ -22,11 +22,12 @@
|
|||||||
<module>ops</module>
|
<module>ops</module>
|
||||||
<module>pay</module>
|
<module>pay</module>
|
||||||
<module>promotion</module>
|
<module>promotion</module>
|
||||||
|
<module>search</module>
|
||||||
</modules>
|
</modules>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<springboot.version>2.1.3.RELEASE</springboot.version>
|
<springboot.version>2.1.4.RELEASE</springboot.version>
|
||||||
<com.alibab.dubbo.version>2.6.5</com.alibab.dubbo.version>
|
<com.alibab.dubbo.version>2.6.5</com.alibab.dubbo.version>
|
||||||
<mysql-connector-java.version>5.1.47</mysql-connector-java.version>
|
<mysql-connector-java.version>5.1.47</mysql-connector-java.version>
|
||||||
<dubbo-spring-boot-starter.version>0.2.1.RELEASE</dubbo-spring-boot-starter.version>
|
<dubbo-spring-boot-starter.version>0.2.1.RELEASE</dubbo-spring-boot-starter.version>
|
||||||
|
@ -13,6 +13,15 @@ public interface ProductSpuService {
|
|||||||
|
|
||||||
CommonResult<ProductSpuDetailBO> getProductSpuDetail(Integer id);
|
CommonResult<ProductSpuDetailBO> getProductSpuDetail(Integer id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增量获得商品列表,按照 lastId 递增获得
|
||||||
|
*
|
||||||
|
* @param lastId 最后查询的编号
|
||||||
|
* @param limit 大小
|
||||||
|
* @return 商品列表
|
||||||
|
*/
|
||||||
|
CommonResult<List<ProductSpuDetailBO>> getProductSpuDetailListForSync(Integer lastId, Integer limit);
|
||||||
|
|
||||||
CommonResult<ProductSpuPageBO> getProductSpuPage(ProductSpuPageDTO productSpuPageDTO);
|
CommonResult<ProductSpuPageBO> getProductSpuPage(ProductSpuPageDTO productSpuPageDTO);
|
||||||
|
|
||||||
CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids);
|
CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids);
|
||||||
|
@ -35,6 +35,10 @@ public class ProductSpuDetailBO implements Serializable {
|
|||||||
* 分类编号
|
* 分类编号
|
||||||
*/
|
*/
|
||||||
private Integer cid;
|
private Integer cid;
|
||||||
|
/**
|
||||||
|
* 分类名
|
||||||
|
*/
|
||||||
|
private String categoryName;
|
||||||
/**
|
/**
|
||||||
* 商品主图地址
|
* 商品主图地址
|
||||||
*
|
*
|
||||||
|
@ -5,6 +5,7 @@ import cn.iocoder.mall.product.api.bo.*;
|
|||||||
import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
|
||||||
|
import cn.iocoder.mall.product.dataobject.ProductCategoryDO;
|
||||||
import cn.iocoder.mall.product.dataobject.ProductSkuDO;
|
import cn.iocoder.mall.product.dataobject.ProductSkuDO;
|
||||||
import cn.iocoder.mall.product.dataobject.ProductSpuDO;
|
import cn.iocoder.mall.product.dataobject.ProductSpuDO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
@ -76,7 +77,8 @@ public interface ProductSpuConvert {
|
|||||||
ProductSkuBO convert4(ProductSkuDO sku);
|
ProductSkuBO convert4(ProductSkuDO sku);
|
||||||
|
|
||||||
@Mappings({}) // TODO 芋艿,后续细看下 mapstruct 的 API ,优化这块
|
@Mappings({}) // TODO 芋艿,后续细看下 mapstruct 的 API ,优化这块
|
||||||
default ProductSpuDetailBO convert2(ProductSpuDO spu, List<ProductSkuDO> skus, List<ProductAttrAndValuePairBO> productAttrDetailBOs) {
|
default ProductSpuDetailBO convert2(ProductSpuDO spu, List<ProductSkuDO> skus, List<ProductAttrAndValuePairBO> productAttrDetailBOs,
|
||||||
|
ProductCategoryDO category) {
|
||||||
// 创建并转换 ProductSpuDetailBO 对象
|
// 创建并转换 ProductSpuDetailBO 对象
|
||||||
ProductSpuDetailBO spuDetail = this.convert2(spu).setPicUrls(StringUtil.split(spu.getPicUrls(), ","));
|
ProductSpuDetailBO spuDetail = this.convert2(spu).setPicUrls(StringUtil.split(spu.getPicUrls(), ","));
|
||||||
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
||||||
@ -93,6 +95,8 @@ public interface ProductSpuConvert {
|
|||||||
List<String> attrs = StringUtil.split(sku.getAttrs(), ",");
|
List<String> attrs = StringUtil.split(sku.getAttrs(), ",");
|
||||||
attrs.forEach(attr -> skuDetail.getAttrs().add(productAttrDetailBOMap.get(Integer.valueOf(attr))));
|
attrs.forEach(attr -> skuDetail.getAttrs().add(productAttrDetailBOMap.get(Integer.valueOf(attr))));
|
||||||
});
|
});
|
||||||
|
// 设置分类名
|
||||||
|
spuDetail.setCategoryName(category.getName());
|
||||||
// 返回
|
// 返回
|
||||||
return spuDetail;
|
return spuDetail;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,16 @@ public interface ProductSpuMapper {
|
|||||||
|
|
||||||
List<ProductSpuDO> selectByIds(@Param("ids") Collection<Integer> ids);
|
List<ProductSpuDO> selectByIds(@Param("ids") Collection<Integer> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得大于 id 的商品编号数组
|
||||||
|
*
|
||||||
|
* @param id 商品编号
|
||||||
|
* @param limit 数量
|
||||||
|
* @return 商品编号数组
|
||||||
|
*/
|
||||||
|
List<Integer> selectIdListByIdGt(@Param("id") Integer id,
|
||||||
|
@Param("limit") Integer limit);
|
||||||
|
|
||||||
void insert(ProductSpuDO productSpuDO);
|
void insert(ProductSpuDO productSpuDO);
|
||||||
|
|
||||||
void update(ProductSpuDO productSpuDO);
|
void update(ProductSpuDO productSpuDO);
|
||||||
@ -29,4 +39,4 @@ public interface ProductSpuMapper {
|
|||||||
@Param("cid") Integer cid,
|
@Param("cid") Integer cid,
|
||||||
@Param("visible") Boolean visible);
|
@Param("visible") Boolean visible);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,10 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
|||||||
return CommonResult.success(true);
|
return CommonResult.success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ProductCategoryDO getProductCategory(Integer productCategoryId) {
|
||||||
|
return productCategoryMapper.selectById(productCategoryId);
|
||||||
|
}
|
||||||
|
|
||||||
public CommonResult<ProductCategoryDO> validProductCategory(Integer productCategoryId) {
|
public CommonResult<ProductCategoryDO> validProductCategory(Integer productCategoryId) {
|
||||||
// 校验分类是否存在
|
// 校验分类是否存在
|
||||||
ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId);
|
ProductCategoryDO productCategory = productCategoryMapper.selectById(productCategoryId);
|
||||||
@ -142,4 +146,4 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
|||||||
|| ProductCategoryConstants.STATUS_DISABLE.equals(status);
|
|| ProductCategoryConstants.STATUS_DISABLE.equals(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import cn.iocoder.mall.product.dataobject.ProductSpuDO;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -54,6 +55,9 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
if (spu == null) {
|
if (spu == null) {
|
||||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
|
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
|
||||||
}
|
}
|
||||||
|
// 获得商品分类分类
|
||||||
|
ProductCategoryDO category = productCategoryService.getProductCategory(spu.getCid());
|
||||||
|
Assert.notNull(category, String.format("分类编号(%d) 对应", spu.getCid()));
|
||||||
// 获得商品 sku 数组
|
// 获得商品 sku 数组
|
||||||
List<ProductSkuDO> skus = productSkuMapper.selectListBySpuIdAndStatus(id, ProductSpuConstants.SKU_STATUS_ENABLE);
|
List<ProductSkuDO> skus = productSkuMapper.selectListBySpuIdAndStatus(id, ProductSpuConstants.SKU_STATUS_ENABLE);
|
||||||
// 获得规格
|
// 获得规格
|
||||||
@ -62,7 +66,20 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||||
false); // 读取规格时,不考虑规格是否被禁用
|
false); // 读取规格时,不考虑规格是否被禁用
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData()));
|
return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData(), category));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<List<ProductSpuDetailBO>> getProductSpuDetailListForSync(Integer lastId, Integer limit) {
|
||||||
|
// TODO 芋艿,这里目前是一个一个进行计算,后续需要优化下
|
||||||
|
// 查询下一批商品编号集合
|
||||||
|
List<Integer> spuIds = productSpuMapper.selectIdListByIdGt(lastId, limit);
|
||||||
|
if (spuIds.isEmpty()) {
|
||||||
|
return CommonResult.success(Collections.emptyList());
|
||||||
|
}
|
||||||
|
// 查询每个商品明细
|
||||||
|
List<ProductSpuDetailBO> spus = spuIds.stream().map(id -> getProductSpuDetail(id).getData()).collect(Collectors.toList()); // TODO 芋艿,此处相当于是 N 个查询,后续要优化。
|
||||||
|
return CommonResult.success(spus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
@ -108,7 +125,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
}
|
}
|
||||||
productSkuMapper.insertList(skus);
|
productSkuMapper.insertList(skus);
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData()));
|
return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData(),
|
||||||
|
validCategoryResult.getData()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("Duplicates")
|
@SuppressWarnings("Duplicates")
|
||||||
|
@ -27,6 +27,20 @@
|
|||||||
AND deleted = 0
|
AND deleted = 0
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectIdListByIdGt" parameterType="Integer" resultType="Integer">
|
||||||
|
SELECT
|
||||||
|
<include refid="FIELDS" />
|
||||||
|
FROM product_spu
|
||||||
|
<where>
|
||||||
|
<if test="id != null">
|
||||||
|
id >= #{id}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
AND deleted = 0
|
||||||
|
ORDER BY id ASC
|
||||||
|
LIMIT #{limit}
|
||||||
|
</select>
|
||||||
|
|
||||||
<insert id="insert" parameterType="ProductSpuDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
<insert id="insert" parameterType="ProductSpuDO" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||||
INSERT INTO product_spu (
|
INSERT INTO product_spu (
|
||||||
name, sell_point, description, cid, pic_urls,
|
name, sell_point, description, cid, pic_urls,
|
||||||
@ -114,4 +128,4 @@
|
|||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
@ -47,5 +47,4 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
21
search/pom.xml
Normal file
21
search/pom.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>mall-parent</artifactId>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>search</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>search-application</module>
|
||||||
|
<module>search-service-api</module>
|
||||||
|
<module>search-service-impl</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
15
search/search-application/pom.xml
Normal file
15
search/search-application/pom.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>search</artifactId>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>search-application</artifactId>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
50
search/search-service-api/pom.xml
Normal file
50
search/search-service-api/pom.xml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>search</artifactId>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>search-service-api</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>common-framework</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.validation</groupId>
|
||||||
|
<artifactId>validation-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-jdk8</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- 提供给 mapstruct 使用 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,12 @@
|
|||||||
|
package cn.iocoder.mall.search.api;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
|
import cn.iocoder.mall.search.api.dto.ProductSearchPageDTO;
|
||||||
|
|
||||||
|
public interface ProductSearchService {
|
||||||
|
|
||||||
|
CommonResult<Integer> rebuild();
|
||||||
|
|
||||||
|
CommonResult searchPage(ProductSearchPageDTO searchPageDTO);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package cn.iocoder.mall.search.api.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品检索分页 DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class ProductSearchPageDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类编号
|
||||||
|
*/
|
||||||
|
private Integer cid;
|
||||||
|
/**
|
||||||
|
* 关键字
|
||||||
|
*/
|
||||||
|
private String keyword;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页码
|
||||||
|
*/
|
||||||
|
private Integer pageNo;
|
||||||
|
/**
|
||||||
|
* 分页大小
|
||||||
|
*/
|
||||||
|
private Integer pageSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序字段数组
|
||||||
|
*/
|
||||||
|
private List<SortFieldDTO> sorts;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package cn.iocoder.mall.search.api.dto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排序字段 DTO
|
||||||
|
*/
|
||||||
|
public class SortFieldDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字段
|
||||||
|
*/
|
||||||
|
private String field;
|
||||||
|
/**
|
||||||
|
* 排序
|
||||||
|
*/
|
||||||
|
private String order;
|
||||||
|
|
||||||
|
}
|
64
search/search-service-impl/pom.xml
Normal file
64
search/search-service-impl/pom.xml
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>search</artifactId>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>search-service-impl</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>search-service-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>product-service-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>order-service-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>dubbo</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- test -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<!-- 提供给 mapstruct 使用 -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,26 @@
|
|||||||
|
package cn.iocoder.mall.search.biz.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ES 字段分析器的枚举类
|
||||||
|
*
|
||||||
|
* 关于 IK 分词,文章 https://blog.csdn.net/xsdxs/article/details/72853288 不错。
|
||||||
|
* 目前项目使用的 ES 版本是 6.7.1 ,可以在 https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-7-1 下载。
|
||||||
|
* 如果不知道怎么安装 ES ,可以看 https://blog.csdn.net/chengyuqiang/article/details/78837712 简单。
|
||||||
|
*/
|
||||||
|
public class FieldAnalyzer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IK 最大化分词
|
||||||
|
*
|
||||||
|
* 会将文本做最细粒度的拆分
|
||||||
|
*/
|
||||||
|
public static final String IK_MAX_WORD = "ik_max_word";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IK 智能分词
|
||||||
|
*
|
||||||
|
* 会做最粗粒度的拆分
|
||||||
|
*/
|
||||||
|
public static final String IK_SMART = "ik_smart";
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package cn.iocoder.mall.search.biz.dao;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
|
||||||
|
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface ProductRepository extends ElasticsearchRepository<ESProductDO, Integer> {
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
ESProductDO findByName(String name);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package cn.iocoder.mall.search.biz.dataobject;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.search.biz.constant.FieldAnalyzer;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Document;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.Field;
|
||||||
|
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品 ES DO
|
||||||
|
*/
|
||||||
|
@Document(indexName = "product", type = "spu", shards = 1, replicas = 0)
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class ESProductDO {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
// ========== 基本信息 =========
|
||||||
|
/**
|
||||||
|
* SPU 名字
|
||||||
|
*/
|
||||||
|
@Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 卖点
|
||||||
|
*/
|
||||||
|
@Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
|
||||||
|
private String sellPoint;
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
@Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 分类编号
|
||||||
|
*/
|
||||||
|
private Integer cid;
|
||||||
|
/**
|
||||||
|
* 分类名
|
||||||
|
*/
|
||||||
|
@Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
|
||||||
|
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,79 @@
|
|||||||
|
package cn.iocoder.mall.search.biz.service;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
|
import cn.iocoder.mall.order.api.CartService;
|
||||||
|
import cn.iocoder.mall.order.api.bo.CalcSkuPriceBO;
|
||||||
|
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||||
|
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
|
||||||
|
import cn.iocoder.mall.search.api.ProductSearchService;
|
||||||
|
import cn.iocoder.mall.search.api.dto.ProductSearchPageDTO;
|
||||||
|
import cn.iocoder.mall.search.biz.dao.ProductRepository;
|
||||||
|
import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@com.alibaba.dubbo.config.annotation.Service(validation = "true")
|
||||||
|
public class ProductSearchServiceImpl implements ProductSearchService {
|
||||||
|
|
||||||
|
private static final Integer REBUILD_FETCH_PER_SIZE = 2;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProductRepository productRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProductSpuService productSpuService;
|
||||||
|
@Autowired
|
||||||
|
private CartService cartService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Integer> rebuild() {
|
||||||
|
// TODO 芋艿,因为目前商品比较少,所以写的很粗暴。等未来重构
|
||||||
|
Integer lastId = null;
|
||||||
|
int rebuildCounts = 0;
|
||||||
|
while (true) {
|
||||||
|
CommonResult<List<ProductSpuDetailBO>> result = productSpuService.getProductSpuDetailListForSync(lastId, REBUILD_FETCH_PER_SIZE);
|
||||||
|
Assert.isTrue(result.isError(), "获得商品列表必然成功");
|
||||||
|
List<ProductSpuDetailBO> spus = result.getData();
|
||||||
|
rebuildCounts += spus.size();
|
||||||
|
// 存储到 ES 中
|
||||||
|
List<ESProductDO> products = spus.stream().map(new Function<ProductSpuDetailBO, ESProductDO>() {
|
||||||
|
@Override
|
||||||
|
public ESProductDO apply(ProductSpuDetailBO spu) {
|
||||||
|
return convert(spu);
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 设置新的 lastId ,或者结束
|
||||||
|
if (spus.size() < REBUILD_FETCH_PER_SIZE) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
lastId = spus.get(spus.size() - 1).getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CommonResult.success(rebuildCounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
||||||
|
private ESProductDO convert(ProductSpuDetailBO spu) {
|
||||||
|
// 获得最小价格的 SKU ,用于下面的价格计算
|
||||||
|
ProductSpuDetailBO.Sku sku = spu.getSkus().stream().min(Comparator.comparing(ProductSpuDetailBO.Sku::getPrice)).get();
|
||||||
|
// 价格计算
|
||||||
|
CommonResult<CalcSkuPriceBO> calSkuPriceResult = cartService.calcSkuPrice(sku.getId());
|
||||||
|
Assert.isTrue(calSkuPriceResult.isError(), String.format("SKU(%d) 价格计算不会出错", sku.getId()));
|
||||||
|
|
||||||
|
return new ESProductDO();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult searchPage(ProductSearchPageDTO searchPageDTO) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
#
|
||||||
|
spring:
|
||||||
|
data:
|
||||||
|
elasticsearch:
|
||||||
|
cluster-name: elasticsearch
|
||||||
|
cluster-nodes: 192.168.88.10:9300
|
||||||
|
repositories:
|
||||||
|
enable: true
|
||||||
|
# dubbo
|
||||||
|
dubbo:
|
||||||
|
application:
|
||||||
|
name: search-service
|
||||||
|
registry:
|
||||||
|
address: zookeeper://127.0.0.1:2181
|
||||||
|
protocol:
|
||||||
|
port: -1
|
||||||
|
name: dubbo
|
||||||
|
scan:
|
||||||
|
base-packages: cn.iocoder.mall.search.service.biz
|
@ -0,0 +1,7 @@
|
|||||||
|
package cn.iocoder.mall.search.biz;
|
||||||
|
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.search"})
|
||||||
|
public class Application {
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package cn.iocoder.mall.search.biz.dao;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||||
|
public class ProductRepositoryTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProductRepository productRepository;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSave() {
|
||||||
|
// productRepository.deleteById(1);
|
||||||
|
ESProductDO product = new ESProductDO()
|
||||||
|
.setId(1)
|
||||||
|
.setName("你猜");
|
||||||
|
productRepository.save(product);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindByName() {
|
||||||
|
ESProductDO product = productRepository.findByName("锤子");
|
||||||
|
System.out.println(product);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user