开始迁移搜索服务
This commit is contained in:
parent
d88da8229f
commit
981b3d87e2
|
@ -0,0 +1,22 @@
|
|||
<?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>common</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mall-spring-boot-starter-rocketmq</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- MQ 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -22,6 +22,7 @@
|
|||
<module>mall-spring-boot-starter-mybatis</module>
|
||||
<module>mall-spring-boot-starter-dubbo</module>
|
||||
<module>mall-spring-boot-starter-system-error-code</module>
|
||||
<module>mall-spring-boot-starter-rocketmq</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
<spring-boot-starter-data-jest.version>3.2.5.RELEASE</spring-boot-starter-data-jest.version>
|
||||
<!-- RPC 相关 -->
|
||||
<dubbo.version>2.7.7</dubbo.version>
|
||||
<!-- MQ 相关 -->
|
||||
<rocketmq-spring-boot-starter.version>2.1.0</rocketmq-spring-boot-starter.version>
|
||||
<!-- Job 相关 -->
|
||||
<xxl-job.version>2.0.1</xxl-job.version>
|
||||
<!-- Transaction 相关 -->
|
||||
|
@ -219,12 +221,25 @@
|
|||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<dependency> <!-- TODO 需要思考下,归类到哪里 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-system-error-code</artifactId> <!-- 错误码 -->
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MQ 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.rocketmq</groupId>
|
||||
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||
<version>${rocketmq-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-rocketmq</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Job 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
|
|
3
pom.xml
3
pom.xml
|
@ -14,7 +14,7 @@
|
|||
<artifactId>onemall</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<modules>
|
||||
<!-- <module>product</module>-->
|
||||
<module>product</module>
|
||||
<!-- <module>order</module>-->
|
||||
<module>common</module>
|
||||
<!-- <module>system</module>-->
|
||||
|
@ -31,6 +31,7 @@
|
|||
<module>shop-web-app</module>
|
||||
<module>product-service-project</module>
|
||||
<module>promotion-service-project</module>
|
||||
<module>search-service-project</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package cn.iocoder.mall.productservice.rpc.sku;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SKU Rpc 接口
|
||||
*/
|
||||
public interface ProductSkuRpc {
|
||||
|
||||
/**
|
||||
* 获得商品 SKU
|
||||
*
|
||||
* @param productSkuId 商品 SKU 编号
|
||||
* @return 商品 SKU
|
||||
*/
|
||||
CommonResult<ProductSkuRespDTO> getProductSku(Integer productSkuId);
|
||||
|
||||
/**
|
||||
* 获得商品 SKU 列表
|
||||
*
|
||||
* @param queryReqDTO 商品 SKU 列表的查询请求 DTO
|
||||
* @return 商品 SKU 列表
|
||||
*/
|
||||
CommonResult<List<ProductSkuRespDTO>> listProductSkus(ProductSkuListQueryReqDTO queryReqDTO);
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package cn.iocoder.mall.productservice.rpc.sku.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 商品 SKU 列表查询 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSkuListQueryReqDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Integer productSkuId;
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Integer productSpuId;
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package cn.iocoder.mall.productservice.rpc.sku.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SKU Response DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSkuRespDTO implements Serializable {
|
||||
|
||||
/**
|
||||
* sku 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 商品编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 规格值编号数组
|
||||
*/
|
||||
private List<Integer> attrValueIds;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -30,6 +30,12 @@
|
|||
<artifactId>product-service-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- MQ 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-rocketmq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 和 Config 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
|
@ -72,6 +78,11 @@
|
|||
<artifactId>mapstruct-jdk8</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package cn.iocoder.mall.productservice.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
|
||||
/**
|
||||
* Spring Aop 配置类
|
||||
*/
|
||||
@Configuration
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
|
||||
public class AopConfiguration {
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
package cn.iocoder.mall.productservice.convert.sku;
|
||||
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSkuDO;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuListQueryBO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Named;
|
||||
|
@ -18,7 +22,18 @@ public interface ProductSkuConvert {
|
|||
List<ProductSkuDO> convertList(List<ProductSkuCreateOrUpdateBO> list);
|
||||
|
||||
@Mapping(source = "attrValueIds", target = "attrs", qualifiedByName = "translatePicUrlsFromStringList")
|
||||
ProductSkuDO convert(ProductSkuCreateOrUpdateBO skuUpdateDTO);
|
||||
ProductSkuDO convert(ProductSkuCreateOrUpdateBO bean);
|
||||
|
||||
@Mapping(source = "attrs", target = "attrValueIds", qualifiedByName = "translateAttrValueIdsFromString")
|
||||
ProductSkuBO convert(ProductSkuDO bean);
|
||||
|
||||
List<ProductSkuBO> convertList02(List<ProductSkuDO> list);
|
||||
|
||||
ProductSkuRespDTO convert(ProductSkuBO bean);
|
||||
|
||||
ProductSkuListQueryBO convert(ProductSkuListQueryReqDTO bean);
|
||||
|
||||
List<ProductSkuRespDTO> convertList03(List<ProductSkuBO> list);
|
||||
|
||||
@Named("translateAttrValueIdsFromString")
|
||||
default List<String> translateAttrValueIdsFromString(String attrValueIdsStar) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.mall.productservice.dal.mysql.dataobject.spu;
|
||||
package cn.iocoder.mall.productservice.dal.mysql.dataobject.sku;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.mall.mybatis.core.dataobject.DeletableDO;
|
|
@ -1,7 +1,8 @@
|
|||
package cn.iocoder.mall.productservice.dal.mysql.mapper.sku;
|
||||
|
||||
import cn.iocoder.mall.mybatis.core.query.QueryWrapperX;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSkuDO;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuListQueryBO;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
@ -18,4 +19,9 @@ public interface ProductSkuMapper extends BaseMapper<ProductSkuDO> {
|
|||
|
||||
void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
|
||||
|
||||
default List<ProductSkuDO> selectList(ProductSkuListQueryBO queryBO) {
|
||||
return selectList(new QueryWrapperX<ProductSkuDO>().eqIfPresent("id", queryBO.getProductSkuId())
|
||||
.eqIfPresent("spu_id", queryBO.getProductSpuId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package cn.iocoder.mall.productservice.manager.sku;
|
||||
|
||||
import cn.iocoder.mall.productservice.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.mall.productservice.service.sku.ProductSkuService;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 商品 SKU Manager
|
||||
*/
|
||||
@Service
|
||||
public class ProductSkuManager {
|
||||
|
||||
@Autowired
|
||||
private ProductSkuService productSkuService;
|
||||
|
||||
/**
|
||||
* 获得商品 SKU
|
||||
*
|
||||
* @param productSkuId 商品 SKU编号
|
||||
* @return 商品 SKU
|
||||
*/
|
||||
public ProductSkuRespDTO getProductSku(Integer productSkuId) {
|
||||
ProductSkuBO productSkuBO = productSkuService.getProductSku(productSkuId);
|
||||
return ProductSkuConvert.INSTANCE.convert(productSkuBO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得商品 SKU 列表
|
||||
*
|
||||
* @param queryReqDTO 商品 SKU 列表的查询请求 DTO
|
||||
* @return 商品 SKU列表
|
||||
*/
|
||||
public List<ProductSkuRespDTO> listProductSkus(ProductSkuListQueryReqDTO queryReqDTO) {
|
||||
List<ProductSkuBO> productSkuBOs = productSkuService.listProductSkus(
|
||||
ProductSkuConvert.INSTANCE.convert(queryReqDTO));
|
||||
return ProductSkuConvert.INSTANCE.convertList03(productSkuBOs);
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
|
|||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.productservice.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.mall.productservice.enums.category.ProductCategoryIdEnum;
|
||||
import cn.iocoder.mall.productservice.mq.producer.ProductMQProducer;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuCreateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuAndSkuUpdateReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.spu.dto.ProductSpuPageReqDTO;
|
||||
|
@ -18,6 +19,7 @@ import cn.iocoder.mall.productservice.service.spu.ProductSpuService;
|
|||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuCreateBO;
|
||||
import cn.iocoder.mall.productservice.service.spu.bo.ProductSpuUpdateBO;
|
||||
import org.springframework.aop.framework.AopContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -42,14 +44,25 @@ public class ProductSpuManager {
|
|||
@Autowired
|
||||
private ProductAttrService productAttrService;
|
||||
|
||||
@Autowired
|
||||
private ProductMQProducer productMQProducer;
|
||||
|
||||
/**
|
||||
* 创建商品 SPU 和 SKU
|
||||
*
|
||||
* @param createDTO 创建商品 SPU 和 SKU DTO
|
||||
* @return 商品 SPU
|
||||
*/
|
||||
@Transactional
|
||||
public Integer createProductSpu(ProductSpuAndSkuCreateReqDTO createDTO) {
|
||||
// 创建商品 SPU 和 SKU。注意,这里要调用 self() 方法,因为需要创建事务,否则会失效
|
||||
Integer spuId = self().createProductSpu0(createDTO);
|
||||
// 发送商品创建的 MQ 消息
|
||||
productMQProducer.sendProductUpdateMessage(spuId);
|
||||
return spuId;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Integer createProductSpu0(ProductSpuAndSkuCreateReqDTO createDTO) {
|
||||
// 校验商品分类是否合法
|
||||
this.checkProductCategory(createDTO.getCid());
|
||||
// 创建商品 SKU 对象,并进行校验
|
||||
|
@ -71,6 +84,14 @@ public class ProductSpuManager {
|
|||
* @param updateDTO 更新商品 SPU DTO
|
||||
*/
|
||||
public void updateProductSpu(ProductSpuAndSkuUpdateReqDTO updateDTO) {
|
||||
// 更新商品 SPU 和 SKU。注意,这里要调用 self() 方法,因为需要创建事务,否则会失效
|
||||
self().updateProductSpu0(updateDTO);
|
||||
// 发送商品创建的 MQ 消息
|
||||
productMQProducer.sendProductUpdateMessage(updateDTO.getId());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void updateProductSpu0(ProductSpuAndSkuUpdateReqDTO updateDTO) {
|
||||
// 校验商品分类是否合法
|
||||
this.checkProductCategory(updateDTO.getCid());
|
||||
// 创建商品 SKU 对象,并进行校验
|
||||
|
@ -171,4 +192,8 @@ public class ProductSpuManager {
|
|||
return attrKeyValueBOs;
|
||||
}
|
||||
|
||||
private ProductSpuManager self() {
|
||||
return (ProductSpuManager) AopContext.currentProxy();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package cn.iocoder.mall.productservice.mq.producer;
|
||||
|
||||
import cn.iocoder.mall.productservice.mq.producer.message.ProductUpdateMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.client.producer.SendResult;
|
||||
import org.apache.rocketmq.client.producer.SendStatus;
|
||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ProductMQProducer {
|
||||
|
||||
@Autowired
|
||||
private RocketMQTemplate rocketMQTemplate;
|
||||
|
||||
public void sendProductUpdateMessage(Integer id) {
|
||||
// TODO 芋艿:后续优化下,考虑下一致性
|
||||
try {
|
||||
SendResult sendResult = rocketMQTemplate.syncSend(ProductUpdateMessage.TOPIC, new ProductUpdateMessage().setId(id));
|
||||
if (!SendStatus.SEND_OK.equals(sendResult.getSendStatus())) {
|
||||
log.error("[sendProductUpdateMessage][product({}) 发送更新消息失败,结果为({})]", id, sendResult);
|
||||
}
|
||||
} catch (Throwable throwable) {
|
||||
log.error("[sendProductUpdateMessage][product({}) 发送更新消息失败,发生异常]", id, throwable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.mall.product.api.message;
|
||||
package cn.iocoder.mall.productservice.mq.producer.message;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
|
@ -0,0 +1,33 @@
|
|||
package cn.iocoder.mall.productservice.rpc.sku;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.mall.productservice.manager.sku.ProductSkuManager;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuListQueryReqDTO;
|
||||
import cn.iocoder.mall.productservice.rpc.sku.dto.ProductSkuRespDTO;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* 商品 SKU Rpc 实现类
|
||||
*/
|
||||
@DubboService
|
||||
public class ProductSkuRpcImpl implements ProductSkuRpc {
|
||||
|
||||
@Autowired
|
||||
private ProductSkuManager productSkuManager;
|
||||
|
||||
@Override
|
||||
public CommonResult<ProductSkuRespDTO> getProductSku(Integer productSkuId) {
|
||||
return success(productSkuManager.getProductSku(productSkuId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResult<List<ProductSkuRespDTO>> listProductSkus(ProductSkuListQueryReqDTO queryReqDTO) {
|
||||
return success(productSkuManager.listProductSkus(queryReqDTO));
|
||||
}
|
||||
|
||||
}
|
|
@ -4,9 +4,11 @@ import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
|||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.mall.productservice.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.spu.ProductSkuDO;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.mall.productservice.dal.mysql.mapper.sku.ProductSkuMapper;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuCreateOrUpdateBO;
|
||||
import cn.iocoder.mall.productservice.service.sku.bo.ProductSkuListQueryBO;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
@ -88,4 +90,27 @@ public class ProductSkuService {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得商品 SKU
|
||||
*
|
||||
* @param productSkuId 商品 SKU 编号
|
||||
* @return 商品 SKU
|
||||
*/
|
||||
public ProductSkuBO getProductSku(Integer productSkuId) {
|
||||
ProductSkuDO productSkuDO = productSkuMapper.selectById(productSkuId);
|
||||
return ProductSkuConvert.INSTANCE.convert(productSkuDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得商品 SKU 列表
|
||||
*
|
||||
* @param queryBO 商品 SKU 列表查询条件 BO
|
||||
* @return 商品 SKU 列表
|
||||
*/
|
||||
public List<ProductSkuBO> listProductSkus(ProductSkuListQueryBO queryBO) {
|
||||
// TODO FROM 芋艿:可能要考虑下,是不是要必须传递条件
|
||||
List<ProductSkuDO> productSkuDOs = productSkuMapper.selectList(queryBO);
|
||||
return ProductSkuConvert.INSTANCE.convertList02(productSkuDOs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* 商品 SKU BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSkuBO {
|
||||
|
||||
/**
|
||||
* sku 编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 商品编号
|
||||
*/
|
||||
private Integer spuId;
|
||||
/**
|
||||
* 状态
|
||||
*
|
||||
* 1-正常
|
||||
* 2-禁用
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 规格值({@link ProductAttrValueDO})数组
|
||||
*
|
||||
* 数组,以逗号分隔
|
||||
*/
|
||||
private String attrs;
|
||||
/**
|
||||
* 价格,单位:分
|
||||
*/
|
||||
private Integer price;
|
||||
/**
|
||||
* 库存数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
/**
|
||||
* 最后更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
private Integer deleted;
|
||||
|
||||
}
|
|
@ -10,7 +10,7 @@ import java.util.List;
|
|||
/**
|
||||
* 商品 SKU 创建或者修改 BO
|
||||
*
|
||||
* 注意,目前该对象是
|
||||
* 注意,目前该对象是搭配 {@link}
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package cn.iocoder.mall.productservice.service.sku.bo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 商品 SKU 列表查询 BO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductSkuListQueryBO {
|
||||
|
||||
/**
|
||||
* 商品 SKU 编号
|
||||
*/
|
||||
private Integer productSkuId;
|
||||
/**
|
||||
* 商品 SPU 编号
|
||||
*/
|
||||
private Integer productSpuId;
|
||||
|
||||
}
|
|
@ -40,6 +40,12 @@ dubbo:
|
|||
ErrorCodeRpc:
|
||||
version: 1.0.0
|
||||
|
||||
# RocketMQ 配置项
|
||||
rocketmq:
|
||||
name-server: 400-infra.server.iocoder.cn:9876
|
||||
producer:
|
||||
group: ${spring.application.name}-producer-group
|
||||
|
||||
# Mall 配置项
|
||||
mall:
|
||||
# 错误码配置项对应 ErrorCodeProperties 配置类
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package cn.iocoder.mall.product.biz.bo.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 商品规格值 VO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrValueBO implements Serializable {
|
||||
|
||||
/**
|
||||
* 规格值编号
|
||||
*/
|
||||
private Integer id;
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
private Integer attrId;
|
||||
/**
|
||||
* 规格值名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package cn.iocoder.mall.product.biz.dto.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* Product 规格添加 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrAddDTO {
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@NotEmpty(message = "规格名不能为空")
|
||||
private String name;
|
||||
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package cn.iocoder.mall.product.biz.dto.attr;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageParam;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 商品规格模块 - 商品规格分页 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ProductAttrPageDTO extends PageParam {
|
||||
/**
|
||||
* 商品规格名字
|
||||
*/
|
||||
private String name;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package cn.iocoder.mall.product.biz.dto.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* Product 规格修改 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrUpdateDTO {
|
||||
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
@NotNull(message = "规格编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@NotEmpty(message = "规格名不能为空")
|
||||
private String name;
|
||||
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.mall.product.biz.dto.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* Product 规格值添加 DTO
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrValueAddDTO {
|
||||
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
@NotNull(message = "规格编号不能为空")
|
||||
private Integer attrId;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@NotEmpty(message = "规格值名不能为空")
|
||||
private String name;
|
||||
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package cn.iocoder.mall.product.biz.dto.attr;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* Product 规格值修改 DTO
|
||||
*
|
||||
* 注意,不允许修改所属规格
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ProductAttrValueUpdateDTO {
|
||||
|
||||
/**
|
||||
* 规格值编号
|
||||
*/
|
||||
@NotNull(message = "规格编号不能为空")
|
||||
private Integer id;
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@NotEmpty(message = "规格名不能为空")
|
||||
private String name;
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package cn.iocoder.mall.product.biz.message;
|
||||
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
/**
|
||||
* Spring Cloud Stream Source 接口
|
||||
*/
|
||||
public interface MQStreamProducer {
|
||||
|
||||
/**
|
||||
* 商品更新 Output
|
||||
*/
|
||||
String PRODUCT_UPDATE_OUTPUT = "product-update-output";
|
||||
|
||||
@Output(PRODUCT_UPDATE_OUTPUT)
|
||||
MessageChannel productUpdateOutput();
|
||||
|
||||
// default boolean sendProductUpdateMessage(ProductUpdateMessage message) {
|
||||
// // 创建 Spring Message 对象
|
||||
// Message<ProductUpdateMessage> springMessage = MessageBuilder.withPayload(message)
|
||||
// .build();
|
||||
// // 发送消息
|
||||
// return productUpdateOutput().send(springMessage);
|
||||
// }
|
||||
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
package cn.iocoder.mall.product.biz.message;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 商品收藏 消费者
|
||||
* @author xiaofeng
|
||||
* @date 2019/07/02 19:57
|
||||
* @version 1.0
|
||||
*/
|
||||
@Service
|
||||
//@RocketMQMessageListener(topic = ProductSpuCollectionMessage.TOPIC, consumerGroup = "product-spu-consumer-group-"
|
||||
// + ProductSpuCollectionMessage.TOPIC)
|
||||
public class UserProductSpuCollectionsConsumer
|
||||
// implements RocketMQListener<ProductSpuCollectionMessage>
|
||||
{
|
||||
|
||||
// @Autowired
|
||||
// private UserProductSpuCollectionsService userProductSpuCollectionsService;
|
||||
//
|
||||
// @Reference(validation = "true", version = "${dubbo.consumer.UserService.version}")
|
||||
// private UserService userService;
|
||||
//
|
||||
// @Override
|
||||
// public void onMessage(ProductSpuCollectionMessage productSpuCollectionMessage) {
|
||||
// UserBO userBO = userService.getUser(productSpuCollectionMessage.getUserId());
|
||||
// if (userBO == null) {
|
||||
// throw ServiceExceptionUtil.exception(UserErrorCodeEnum.USER_NOT_EXISTS.getCode());
|
||||
// }
|
||||
// // 收藏
|
||||
// if (productSpuCollectionMessage.getHasCollectionType().equals(1)) {
|
||||
// this.saveUserProductSpuCollections(productSpuCollectionMessage, userBO.getNickname());
|
||||
// } else if (productSpuCollectionMessage.getHasCollectionType().equals(2)) {
|
||||
// // 取消收藏
|
||||
// this.deleteUserProductSpuCollections(productSpuCollectionMessage.getUserId(),
|
||||
// productSpuCollectionMessage.getSpuId());
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 保存商品收藏
|
||||
// * @param productSpuCollectionMessage
|
||||
// * @param nickname
|
||||
// * @return
|
||||
// */
|
||||
// private int saveUserProductSpuCollections(final ProductSpuCollectionMessage productSpuCollectionMessage,
|
||||
// final String nickname) {
|
||||
// int result = 0;
|
||||
// UserProductSpuCollectionsBO userProductSpuCollectionsBO = this.userProductSpuCollectionsService
|
||||
// .getUserSpuCollectionsByUserIdAndSpuId(productSpuCollectionMessage.getUserId(),
|
||||
// productSpuCollectionMessage.getSpuId());
|
||||
// if (userProductSpuCollectionsBO == null) {
|
||||
// UserProductSpuCollectionsAddDTO userProductSpuCollectionsAddDTO = UserProductSpuCollectionsConvert.INSTANCE
|
||||
// .convert(productSpuCollectionMessage);
|
||||
// userProductSpuCollectionsAddDTO.setNickname(StringUtils.isEmpty(nickname) ? "" : nickname);
|
||||
// userProductSpuCollectionsAddDTO.setCreateTime(new Date());
|
||||
// userProductSpuCollectionsAddDTO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
// result = userProductSpuCollectionsService.addUserSkuCollections(userProductSpuCollectionsAddDTO);
|
||||
// } else {
|
||||
// // 存在重新收藏
|
||||
// if (userProductSpuCollectionsBO.getDeleted().equals(DeletedStatusEnum.DELETED_YES.getValue())) {
|
||||
// UserProductSpuCollectionsUpdateDTO userProductSpuCollectionsUpdateDTO = this
|
||||
// .setUserProductSpuCollectionsUpdateDTO(userProductSpuCollectionsBO.getId(),
|
||||
// DeletedStatusEnum.DELETED_NO);
|
||||
// result = this.userProductSpuCollectionsService
|
||||
// .updateUserProductSpuCollections(userProductSpuCollectionsUpdateDTO);
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 取消收藏
|
||||
// * @param userId
|
||||
// * @param spuId
|
||||
// * @return
|
||||
// */
|
||||
// private int deleteUserProductSpuCollections(final Integer userId, final Integer spuId) {
|
||||
// UserProductSpuCollectionsBO userProductSpuCollectionsBO = this.userProductSpuCollectionsService
|
||||
// .getUserSpuCollectionsByUserIdAndSpuId(userId, spuId);
|
||||
// int result = 0;
|
||||
// if (userProductSpuCollectionsBO != null) {
|
||||
// // 未取消收藏的数据
|
||||
// if (userProductSpuCollectionsBO.getDeleted().equals(DeletedStatusEnum.DELETED_NO.getValue())) {
|
||||
// UserProductSpuCollectionsUpdateDTO userProductSpuCollectionsUpdateDTO = this
|
||||
// .setUserProductSpuCollectionsUpdateDTO(userProductSpuCollectionsBO.getId(),
|
||||
// DeletedStatusEnum.DELETED_YES);
|
||||
// result = this.userProductSpuCollectionsService
|
||||
// .updateUserProductSpuCollections(userProductSpuCollectionsUpdateDTO);
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 设置更新值
|
||||
// * @param id
|
||||
// * @param deletedStatusEnum
|
||||
// * @return
|
||||
// */
|
||||
// private UserProductSpuCollectionsUpdateDTO setUserProductSpuCollectionsUpdateDTO(final Integer id,
|
||||
// final DeletedStatusEnum deletedStatusEnum) {
|
||||
// return new UserProductSpuCollectionsUpdateDTO().setId(id).setUpdateTime(new Date())
|
||||
// .setDeleted(deletedStatusEnum.getValue());
|
||||
// }
|
||||
|
||||
|
||||
}
|
|
@ -1,26 +1,10 @@
|
|||
package cn.iocoder.mall.product.biz.service.attr;
|
||||
|
||||
import cn.iocoder.common.framework.enums.CommonStatusEnum;
|
||||
import cn.iocoder.common.framework.validator.InEnum;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrSimpleWithValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrWithValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.product.ProductAttrAndValuePairBO;
|
||||
import cn.iocoder.mall.product.biz.dto.attr.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface ProductAttrService {
|
||||
/**
|
||||
* 获取规格分页数据
|
||||
*
|
||||
* @param productAttrPageDTO 查询参数
|
||||
* @return 规格分页信息
|
||||
*/
|
||||
PageResult<ProductAttrWithValueBO> getProductAttrPage(ProductAttrPageDTO productAttrPageDTO);
|
||||
|
||||
/**
|
||||
* 获得规格属性数组
|
||||
|
@ -31,40 +15,4 @@ public interface ProductAttrService {
|
|||
*/
|
||||
List<ProductAttrSimpleWithValueBO> getProductAttrList();
|
||||
|
||||
/**
|
||||
* 添加商品规格
|
||||
*
|
||||
* @param adminId 操作人ID
|
||||
* @param productAttrAddDTO 添加参数
|
||||
* @return 添加的规格
|
||||
*/
|
||||
ProductAttrBO addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO);
|
||||
|
||||
/**
|
||||
* 更新规格
|
||||
*
|
||||
* @param adminId 操作人
|
||||
* @param productAttrUpdateDTO 更新规格
|
||||
* @return 成功标识
|
||||
*/
|
||||
Boolean updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO);
|
||||
|
||||
/**
|
||||
* 更新规格状态
|
||||
*
|
||||
* @param adminId 操作人
|
||||
* @param productAttrId 规格ID
|
||||
* @param status 状态
|
||||
* @return 成功标识
|
||||
*/
|
||||
Boolean updateProductAttrStatus(Integer adminId, Integer productAttrId, Integer status);
|
||||
|
||||
ProductAttrValueBO addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO);
|
||||
|
||||
Boolean updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO);
|
||||
|
||||
Boolean updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId,
|
||||
@InEnum(value = CommonStatusEnum.class, message = "修改状态必须是 {value}") Integer status);
|
||||
|
||||
List<ProductAttrAndValuePairBO> validProductAttrAndValue(Set<Integer> productAttrValueIds, boolean validStatus);
|
||||
}
|
||||
|
|
|
@ -37,34 +37,6 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
public class ProductAttrServiceImpl implements ProductAttrService {
|
||||
|
||||
@Autowired
|
||||
private ProductAttrMapper productAttrMapper;
|
||||
@Autowired
|
||||
private ProductAttrValueMapper productAttrValueMapper;
|
||||
|
||||
@Override
|
||||
public PageResult<ProductAttrWithValueBO> getProductAttrPage(ProductAttrPageDTO productAttrPageDTO) {
|
||||
//查询分页
|
||||
Page<ProductAttrDO> page = new Page<>(productAttrPageDTO.getPageNo(), productAttrPageDTO.getPageSize());
|
||||
LambdaQueryWrapper<ProductAttrDO> queryWrapper = Wrappers.<ProductAttrDO>query().lambda()
|
||||
.like(StringUtils.isNotBlank(productAttrPageDTO.getName()), ProductAttrDO::getName, productAttrPageDTO.getName())
|
||||
.eq(ProductAttrDO::getDeleted, false);
|
||||
IPage<ProductAttrDO> attrPage = productAttrMapper.selectPage(page, queryWrapper);
|
||||
PageResult<ProductAttrWithValueBO> productAttrPage = ProductAttrConvert.INSTANCE.convertPage(attrPage);
|
||||
// 将规格值拼接上去
|
||||
if (!CollectionUtil.isEmpty(productAttrPage.getList())) {
|
||||
Set<Integer> attrIds = productAttrPage.getList().stream().map(ProductAttrBO::getId).collect(Collectors.toSet());
|
||||
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectList(Wrappers.<ProductAttrValueDO>query().lambda()
|
||||
.in(ProductAttrValueDO::getAttrId, attrIds)
|
||||
.eq(ProductAttrValueDO::getDeleted, false));
|
||||
Map<Integer, List<ProductAttrValueDO>> attrValueMap = attrValues.stream().collect(Collectors.groupingBy(ProductAttrValueDO::getAttrId));
|
||||
for (ProductAttrWithValueBO item : productAttrPage.getList()) {
|
||||
item.setValues(ProductAttrConvert.INSTANCE.convertAttrValues(attrValueMap.get(item.getId())));
|
||||
}
|
||||
}
|
||||
return productAttrPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductAttrSimpleWithValueBO> getProductAttrList() {
|
||||
// 查询所有开启的规格数组
|
||||
|
@ -87,157 +59,4 @@ public class ProductAttrServiceImpl implements ProductAttrService {
|
|||
return attrs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductAttrBO addProductAttr(Integer adminId, ProductAttrAddDTO productAttrAddDTO) {
|
||||
// 校验规格名不重复
|
||||
int count = productAttrMapper.selectCount(Wrappers.<ProductAttrDO>query().lambda()
|
||||
.eq(ProductAttrDO::getName, productAttrAddDTO.getName())
|
||||
.eq(ProductAttrDO::getDeleted, false));
|
||||
if (count > 0) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_EXISTS.getCode());
|
||||
}
|
||||
// 插入到数据库
|
||||
ProductAttrDO productAttrDO = new ProductAttrDO().setName(productAttrAddDTO.getName())
|
||||
.setStatus(ProductAttrConstants.ATTR_STATUS_ENABLE);
|
||||
productAttrDO.setCreateTime(new Date());
|
||||
productAttrDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
productAttrMapper.insert(productAttrDO);
|
||||
// 返回成功
|
||||
return ProductAttrConvert.INSTANCE.convertAttr(productAttrDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateProductAttr(Integer adminId, ProductAttrUpdateDTO productAttrUpdateDTO) {
|
||||
// 校验存在
|
||||
if (productAttrMapper.selectById(productAttrUpdateDTO.getId()) == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode());
|
||||
}
|
||||
// 校验规格名不重复
|
||||
ProductAttrDO existsAttrDO = productAttrMapper.selectOne(Wrappers.<ProductAttrDO>query().lambda()
|
||||
.eq(ProductAttrDO::getName, productAttrUpdateDTO.getName())
|
||||
.eq(ProductAttrDO::getDeleted, false));
|
||||
if (existsAttrDO != null && !existsAttrDO.getId().equals(productAttrUpdateDTO.getId())) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_EXISTS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
ProductAttrDO updateProductAttr = ProductAttrConvert.INSTANCE.convertUpdate(productAttrUpdateDTO);
|
||||
updateProductAttr.setUpdateTime(new Date());
|
||||
int i = productAttrMapper.updateById(updateProductAttr);
|
||||
// 返回成功
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean updateProductAttrStatus(Integer adminId, Integer productAttrId, Integer status) {
|
||||
// 校验存在
|
||||
ProductAttrDO productAttrDO = productAttrMapper.selectById(productAttrId);
|
||||
if (productAttrDO == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode());
|
||||
}
|
||||
// 校验状态
|
||||
if (productAttrDO.getStatus().equals(status)) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_STATUS_EQUALS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
ProductAttrDO updateProductAttr = new ProductAttrDO().setId(productAttrId).setStatus(status);
|
||||
int i = productAttrMapper.updateById(updateProductAttr);
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductAttrValueBO addProductAttrValue(Integer adminId, ProductAttrValueAddDTO productAttrValueAddDTO) {
|
||||
// 校验规格名不重复
|
||||
int count = productAttrValueMapper.selectCount(Wrappers.<ProductAttrValueDO>query().lambda()
|
||||
.eq(ProductAttrValueDO::getName, productAttrValueAddDTO.getName())
|
||||
.eq(ProductAttrValueDO::getAttrId, productAttrValueAddDTO.getAttrId())
|
||||
.eq(ProductAttrValueDO::getDeleted, false));
|
||||
if (count > 0) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_EXISTS.getCode());
|
||||
}
|
||||
// 插入到数据库
|
||||
ProductAttrValueDO productAttrValueDO = ProductAttrConvert.INSTANCE.convertValueAdd(productAttrValueAddDTO)
|
||||
.setStatus(ProductAttrConstants.ATTR_VALUE_STATUS_ENABLE);
|
||||
productAttrValueDO.setCreateTime(new Date());
|
||||
productAttrValueDO.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
productAttrValueMapper.insert(productAttrValueDO);
|
||||
return ProductAttrConvert.INSTANCE.convertAttrValue(productAttrValueDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateProductAttrValue(Integer adminId, ProductAttrValueUpdateDTO productAttrValueUpdateDTO) {
|
||||
// 校验存在
|
||||
ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueUpdateDTO.getId());
|
||||
if (productAttrValueDO == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode());
|
||||
}
|
||||
// 校验规格名不重复
|
||||
ProductAttrValueDO existsAttrDO = productAttrValueMapper.selectOne(Wrappers.<ProductAttrValueDO>query().lambda()
|
||||
.eq(ProductAttrValueDO::getName, productAttrValueDO.getName())
|
||||
.eq(ProductAttrValueDO::getAttrId, productAttrValueDO.getAttrId())
|
||||
.eq(ProductAttrValueDO::getDeleted, false));
|
||||
if (existsAttrDO != null && !existsAttrDO.getId().equals(productAttrValueUpdateDTO.getId())) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_EXISTS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
ProductAttrValueDO updateProductValue = ProductAttrConvert.INSTANCE.convertValueUpdate(productAttrValueUpdateDTO);
|
||||
updateProductValue.setUpdateTime(new Date());
|
||||
int i = productAttrValueMapper.updateById(updateProductValue);
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateProductAttrValueStatus(Integer adminId, Integer productAttrValueId, Integer status) {
|
||||
// 校验存在
|
||||
ProductAttrValueDO productAttrValueDO = productAttrValueMapper.selectById(productAttrValueId);
|
||||
if (productAttrValueDO == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode());
|
||||
}
|
||||
// 校验状态
|
||||
if (productAttrValueDO.getStatus().equals(status)) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_STATUS_EQUALS.getCode());
|
||||
}
|
||||
// 更新到数据库
|
||||
ProductAttrValueDO updateProductAttrValue = new ProductAttrValueDO().setId(productAttrValueId).setStatus(status);
|
||||
int i = productAttrValueMapper.updateById(updateProductAttrValue);
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProductAttrAndValuePairBO> validProductAttrAndValue(Set<Integer> productAttrValueIds, boolean validStatus) {
|
||||
// 首先,校验规格值
|
||||
List<ProductAttrValueDO> attrValues = productAttrValueMapper.selectBatchIds(productAttrValueIds);
|
||||
if (attrValues.size() != productAttrValueIds.size()) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode());
|
||||
}
|
||||
if (validStatus) {
|
||||
// 同时,校验下状态
|
||||
for (ProductAttrValueDO attrValue : attrValues) {
|
||||
if (ProductAttrConstants.ATTR_STATUS_DISABLE.equals(attrValue.getStatus())) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_VALUE_NOT_EXIST.getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 然后,校验规格
|
||||
Set<Integer> attrIds = attrValues.stream().map(ProductAttrValueDO::getAttrId).collect(Collectors.toSet());
|
||||
List<ProductAttrDO> attrs = productAttrMapper.selectBatchIds(attrIds);
|
||||
if (attrs.size() != attrIds.size()) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode());
|
||||
}
|
||||
if (validStatus) {
|
||||
// 同时,校验下状态
|
||||
for (ProductAttrDO attr : attrs) {
|
||||
if (ProductAttrConstants.ATTR_VALUE_STATUS_DISABLE.equals(attr.getStatus())) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_ATTR_NOT_EXIST.getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 返回成功
|
||||
// ProductAttrDO 的映射,方便查找。
|
||||
Map<Integer, ProductAttrDO> attrMap = attrs.stream().collect(Collectors.toMap(ProductAttrDO::getId, productAttrDO -> productAttrDO));
|
||||
return attrValues.stream().map(productAttrValueDO -> new ProductAttrAndValuePairBO()
|
||||
.setAttrId(productAttrValueDO.getAttrId()).setAttrName(attrMap.get(productAttrValueDO.getAttrId()).getName())
|
||||
.setAttrValueId(productAttrValueDO.getId()).setAttrValueName(productAttrValueDO.getName())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -62,109 +62,4 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
return ProductSpuConvert.INSTANCE.convert2(spu, skus, attrAndValuePairList, category);
|
||||
}
|
||||
|
||||
public ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
|
||||
ProductSpuDetailBO productSpuDetailBO = addProductSpu0(adminId, productSpuAddDTO);
|
||||
// 如果新增生成,发送创建商品 Topic 消息
|
||||
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
|
||||
// sendProductUpdateMessage(productSpuDetailBO.getId());
|
||||
// 返回成功
|
||||
return productSpuDetailBO;
|
||||
}
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Transactional
|
||||
public ProductSpuDetailBO addProductSpu0(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
|
||||
// 校验商品分类分类存在
|
||||
ProductCategoryDO category = productCategoryService.validProductCategory(productSpuAddDTO.getCid());
|
||||
if (ProductCategoryNodeEnum.ROOT.getId().equals(category.getPid())) {
|
||||
// 商品只能添加到二级分类下
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode());
|
||||
}
|
||||
// 校验规格是否存在
|
||||
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||
productSpuAddDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs()));
|
||||
// 读取规格时,需要考虑规格是否被禁用
|
||||
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds, true);
|
||||
// 保存 Spu
|
||||
ProductSpuDO spu = ProductSpuConvert.INSTANCE.convertToSpuDO(productSpuAddDTO)
|
||||
.setPicUrls(StringUtil.join(productSpuAddDTO.getPicUrls(), ","))
|
||||
.setSort(0); // 排序为 0
|
||||
spu.setCreateTime(new Date());
|
||||
spu.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
// 初始化 sku 相关信息到 spu 中
|
||||
initSpuFromSkus(spu, productSpuAddDTO.getSkus());
|
||||
productSpuMapper.insert(spu);
|
||||
// 保存 Sku
|
||||
List<ProductSkuDO> skus = productSpuAddDTO.getSkus().stream().map(productSkuAddDTO -> {
|
||||
ProductSkuDO sku = ProductSpuConvert.INSTANCE.convertToSkuDO(productSkuAddDTO)
|
||||
.setSpuId(spu.getId())
|
||||
.setStatus(ProductSpuConstants.SKU_STATUS_ENABLE)
|
||||
.setAttrs(StringUtil.join(productSkuAddDTO.getAttrs(), ","));
|
||||
sku.setCreateTime(new Date());
|
||||
sku.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
|
||||
return sku;
|
||||
}).collect(Collectors.toList());
|
||||
// 校验 Sku 规格
|
||||
validProductSku(productSpuAddDTO.getSkus(), attrAndValuePairList);
|
||||
// 插入 SKU 到数据库
|
||||
productSkuMapper.insertList(skus);
|
||||
// 返回成功
|
||||
return ProductSpuConvert.INSTANCE.convert2(spu, skus, attrAndValuePairList, category);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 sku 数组,计算相关的字段到 spu 中。
|
||||
*
|
||||
* @param spu spu
|
||||
* @param skus sku 数组
|
||||
*/
|
||||
private void initSpuFromSkus(ProductSpuDO spu, List<ProductSkuAddOrUpdateDTO> skus) {
|
||||
assert skus.size() > 0; // 写个断言,避免下面警告
|
||||
spu.setPrice(skus.stream().min(Comparator.comparing(ProductSkuAddOrUpdateDTO::getPrice)).get().getPrice()); // 求最小价格
|
||||
spu.setQuantity(skus.stream().mapToInt(ProductSkuAddOrUpdateDTO::getQuantity).sum()); // 求库存之和
|
||||
}
|
||||
|
||||
// private boolean sendProductUpdateMessage(Integer id) {
|
||||
// // 创建 Message 对象
|
||||
// ProductUpdateMessage message = new ProductUpdateMessage().setId(id);
|
||||
// // 创建 Spring Message 对象
|
||||
// Message<ProductUpdateMessage> springMessage = MessageBuilder.withPayload(message)
|
||||
// .build();
|
||||
// // 发送消息
|
||||
// return mqStreamProducer.productUpdateOutput().send(springMessage);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 校验 sku 是否合法
|
||||
*
|
||||
* @param productSkuAddDTOs sku 添加或修改信息
|
||||
* @param productAttrDetailBOs 商品规格明细数组
|
||||
*/
|
||||
private void validProductSku(List<ProductSkuAddOrUpdateDTO> productSkuAddDTOs, List<ProductAttrAndValuePairBO> productAttrDetailBOs) {
|
||||
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
||||
Map<Integer, ProductAttrAndValuePairBO> productAttrDetailBOMap = productAttrDetailBOs.stream().collect(
|
||||
Collectors.toMap(ProductAttrAndValuePairBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
|
||||
// 1. 先校验,一个 Sku 下,没有重复的规格。校验方式是,遍历每个 Sku ,看看是否有重复的规格 attrId
|
||||
for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) {
|
||||
Set<Integer> attrIds = sku.getAttrs().stream().map(attrValueId -> productAttrDetailBOMap.get(attrValueId).getAttrId())
|
||||
.collect(Collectors.toSet());
|
||||
if (attrIds.size() != sku.getAttrs().size()) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE.getCode());
|
||||
}
|
||||
}
|
||||
// 2. 再校验,每个 Sku 的规格值的数量,是一致的。
|
||||
int attrSize = productSkuAddDTOs.get(0).getAttrs().size();
|
||||
for (int i = 1; i < productSkuAddDTOs.size(); i++) {
|
||||
if (attrSize != productSkuAddDTOs.get(i).getAttrs().size()) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_ATTR_NUMBERS_MUST_BE_EQUALS.getCode());
|
||||
}
|
||||
}
|
||||
// 3. 最后校验,每个 Sku 之间不是重复的
|
||||
Set<Set<Integer>> skuAttrValues = new HashSet<>(); // 每个元素,都是一个 Sku 的 attrValueId 集合。这样,通过最外层的 Set ,判断是否有重复的.
|
||||
for (ProductSkuAddOrUpdateDTO sku : productSkuAddDTOs) {
|
||||
if (!skuAttrValues.add(new HashSet<>(sku.getAttrs()))) { // 添加失败,说明重复
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_SKU__NOT_DUPLICATE.getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
##################### 业务模块 #####################
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
spring:
|
||||
# 数据源配置项
|
||||
datasource:
|
||||
url: jdbc:mysql://s1.iocoder.cn:3306/mall_product?useSSL=false&useUnicode=true&characterEncoding=UTF-8
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
username: root
|
||||
password: 3WLiVUBEwTbvAfsh
|
||||
|
||||
# MyBatis Plus 配置项
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: auto
|
||||
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
|
||||
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
|
||||
mapper-locations: classpath*:mapper/*.xml
|
||||
type-aliases-package: cn.iocoder.mall.product.biz.dataobject
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.mall.product.biz.dao.sku.ProductSkuMapper">
|
||||
|
||||
|
||||
<insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||
INSERT INTO product_sku (
|
||||
spu_id, status, pic_url, attrs, price,
|
||||
quantity, deleted, create_time
|
||||
) VALUES
|
||||
<foreach collection="productSkuDOs" item="productSkuDO" separator=",">
|
||||
(#{productSkuDO.spuId}, #{productSkuDO.status}, #{productSkuDO.picUrl}, #{productSkuDO.attrs}, #{productSkuDO.price},
|
||||
#{productSkuDO.quantity}, #{productSkuDO.deleted}, #{productSkuDO.createTime}
|
||||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
|
||||
</mapper>
|
|
@ -43,15 +43,6 @@ public class AdminsProductAttrController {
|
|||
@Autowired
|
||||
private ProductAttrService productAttrService;
|
||||
|
||||
@GetMapping("/attr/page")
|
||||
@ApiOperation("获得规格分页")
|
||||
public CommonResult<PageResult<AdminsProductAttrPageResponse>> attrPage(ProductAttrPageRequest request) {
|
||||
ProductAttrPageDTO pageDTO = ProductAttrConvert.INSTANCE.convert(request);
|
||||
PageResult<ProductAttrWithValueBO> productAttrPage = productAttrService.getProductAttrPage(pageDTO);
|
||||
PageResult<AdminsProductAttrPageResponse> adminPageResponse = ProductAttrConvert.INSTANCE.convertPage(productAttrPage);
|
||||
return CommonResult.success(adminPageResponse);
|
||||
}
|
||||
|
||||
@GetMapping("/attr/tree")
|
||||
@ApiOperation(value = "获得规格树结构", notes = "该接口返回的信息更为精简。一般用于前端缓存数据字典到本地。")
|
||||
public CommonResult<List<AdminsProductAttrSimpleResponse>> tree() {
|
||||
|
@ -60,76 +51,4 @@ public class AdminsProductAttrController {
|
|||
return CommonResult.success(ProductAttrConvert.INSTANCE.convertSimple(result));
|
||||
}
|
||||
|
||||
@PostMapping("/attr/add")
|
||||
@ApiOperation(value = "创建商品规格")
|
||||
public CommonResult<AdminsProdutAttrResponse> addAttr(@Validated ProductAttrAddRequest addRequest) {
|
||||
// 创建 ProductAttrAddDTO 对象
|
||||
ProductAttrAddDTO productAttrAddDTO = new ProductAttrAddDTO().setName(addRequest.getName());
|
||||
// 添加
|
||||
ProductAttrBO result = productAttrService.addProductAttr(AdminSecurityContextHolder.getContext().getAdminId(), productAttrAddDTO);
|
||||
return CommonResult.success(ProductAttrConvert.INSTANCE.convertAttr(result));
|
||||
}
|
||||
|
||||
@PostMapping("/attr/update")
|
||||
@ApiOperation(value = "修改商品规格")
|
||||
public CommonResult<Boolean> updateAttr(@Validated ProductAttrUpdateRequest updateRequest) {
|
||||
ProductAttrUpdateDTO productAttrUpdateDTO = ProductAttrConvert.INSTANCE.convertUpdate(updateRequest);
|
||||
// 更新
|
||||
return CommonResult.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<Boolean> updateAttrStatus(@RequestParam("id") Integer id,
|
||||
@RequestParam("status") Integer status) {
|
||||
return CommonResult.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<AdminsProductAttrValueResponse> addAttrValue(@Validated ProductAttrValueAddRequest addRequest) {
|
||||
// 创建 ProductAttrValueAddDTO 对象
|
||||
ProductAttrValueAddDTO productAttrValueAddDTO = new ProductAttrValueAddDTO().setAttrId(addRequest.getAttrId()).setName(addRequest.getName());
|
||||
// 添加
|
||||
ProductAttrValueBO result = productAttrService.addProductAttrValue(AdminSecurityContextHolder.getContext().getAdminId(), productAttrValueAddDTO);
|
||||
// 返回结果
|
||||
return CommonResult.success(ProductAttrConvert.INSTANCE.convertAddResponse(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<Boolean> updateAttrValue(@RequestParam("id") Integer id,
|
||||
@RequestParam("name") String name) {
|
||||
// 创建 ProductAttrValueUpdateDTO 对象
|
||||
ProductAttrValueUpdateDTO productAttrValueUpdateDTO = new ProductAttrValueUpdateDTO().setId(id).setName(name);
|
||||
// 更新
|
||||
return CommonResult.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<Boolean> updateAttrValueStatus(@RequestParam("id") Integer id,
|
||||
@RequestParam("status") Integer status) {
|
||||
return CommonResult.success(productAttrService.updateProductAttrValueStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status));
|
||||
}
|
||||
|
||||
// TODO 芋艿 暂时不考虑 delete Attr Value 。因为关联逻辑比较多
|
||||
|
||||
}
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
package cn.iocoder.mall.product.rest.controller.brand;
|
||||
|
||||
import cn.iocoder.common.framework.vo.CommonResult;
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.product.biz.bo.brand.ProductBrandBO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandAddDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandPageDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandUpdateDTO;
|
||||
import cn.iocoder.mall.product.biz.service.brand.ProductBrandService;
|
||||
import cn.iocoder.mall.product.rest.convert.brand.ProductBrandConvert;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandAddRequest;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandPageRequest;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandUpdateRequest;
|
||||
import cn.iocoder.mall.product.rest.response.brand.AdminsProductBrandResponse;
|
||||
import cn.iocoder.mall.security.core.context.AdminSecurityContextHolder;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.common.framework.vo.CommonResult.success;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("admins/brand")
|
||||
@Api("管理员 - 商品品牌 API")
|
||||
@AllArgsConstructor
|
||||
public class AdminsProductBrandController {
|
||||
|
||||
private final ProductBrandService productBrandService;
|
||||
|
||||
@PostMapping("/add")
|
||||
@ApiOperation("创建品牌")
|
||||
public CommonResult<AdminsProductBrandResponse> add(@Validated ProductBrandAddRequest addRequest) {
|
||||
// 创建 ProductBrandAddDTO 对象
|
||||
ProductBrandAddDTO productBrandAddDTO = ProductBrandConvert.INSTANCE.convertAdd(addRequest);
|
||||
// 保存品牌
|
||||
ProductBrandBO result = productBrandService.addProductBrand(AdminSecurityContextHolder.getContext().getAdminId(), productBrandAddDTO);
|
||||
// 返回结果
|
||||
return success(ProductBrandConvert.INSTANCE.convert(result));
|
||||
}
|
||||
|
||||
@PostMapping("/update")
|
||||
@ApiOperation("更新商品")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "品牌主键", required = true, example = "1"),
|
||||
@ApiImplicitParam(name = "name", value = "品牌名称", required = true, example = "安踏"),
|
||||
@ApiImplicitParam(name = "description", value = "品牌描述", required = true, example = "安踏拖鞋"),
|
||||
@ApiImplicitParam(name = "picUrl", value = "品牌图片", required = true, example = "http://www.iocoder.cn"),
|
||||
@ApiImplicitParam(name = "status", value = "状态 1开启 2禁用", required = true, example = "1")
|
||||
})
|
||||
// TODO FROM 芋艿 to q2118cs:只要改成了 bean 接收,就不用在写 @ApiImplicitParam 注解啦,直接在 bean 里写就 ok 啦
|
||||
public CommonResult<Boolean> update(@Validated ProductBrandUpdateRequest updateRequest) {
|
||||
// 创建 productBrandUpdateDTO 对象
|
||||
ProductBrandUpdateDTO productBrandUpdateDTO = ProductBrandConvert.INSTANCE.convertUpdate(updateRequest);
|
||||
// 更新商品
|
||||
return success(productBrandService.updateProductBrand(AdminSecurityContextHolder.getContext().getAdminId(), productBrandUpdateDTO));
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获取品牌")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "id", value = "品牌主键", required = true, example = "1")
|
||||
})
|
||||
public CommonResult<AdminsProductBrandResponse> add(@RequestParam("id") Integer id) {
|
||||
// 保存商品
|
||||
ProductBrandBO result = productBrandService.getProductBrand(id);
|
||||
// 返回结果
|
||||
return success(ProductBrandConvert.INSTANCE.convert(result));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得品牌分页")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "name", value = "品牌名称", required = true, example = "安踏"),
|
||||
@ApiImplicitParam(name = "description", value = "品牌描述", required = true, example = "安踏拖鞋"),
|
||||
@ApiImplicitParam(name = "status", value = "状态 1开启 2禁用", required = true, example = "1"),
|
||||
@ApiImplicitParam(name = "pageNo", value = "页码", required = true, example = "1"),
|
||||
@ApiImplicitParam(name = "pageSize", value = "页面大小", required = true, example = "10")
|
||||
})
|
||||
public CommonResult<PageResult<AdminsProductBrandResponse>> attrPage(ProductBrandPageRequest pageRequest) {
|
||||
// 创建 ProductBrandPageDTO 对象
|
||||
ProductBrandPageDTO productBrandPageDTO = ProductBrandConvert.INSTANCE.convertPageRequest(pageRequest);
|
||||
// 查询分页
|
||||
PageResult<ProductBrandBO> productBrandPage = productBrandService.getProductBrandPage(productBrandPageDTO);
|
||||
PageResult<AdminsProductBrandResponse> adminPageResponse = ProductBrandConvert.INSTANCE.convertPage(productBrandPage);
|
||||
return CommonResult.success(adminPageResponse);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,18 +1,7 @@
|
|||
package cn.iocoder.mall.product.rest.convert.attr;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrSimpleWithValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrValueBO;
|
||||
import cn.iocoder.mall.product.biz.bo.attr.ProductAttrWithValueBO;
|
||||
import cn.iocoder.mall.product.biz.dto.attr.ProductAttrPageDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.attr.ProductAttrUpdateDTO;
|
||||
import cn.iocoder.mall.product.rest.request.attr.ProductAttrPageRequest;
|
||||
import cn.iocoder.mall.product.rest.request.attr.ProductAttrUpdateRequest;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProductAttrPageResponse;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProductAttrSimpleResponse;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProdutAttrResponse;
|
||||
import cn.iocoder.mall.product.rest.response.attr.AdminsProductAttrValueResponse;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
@ -24,22 +13,8 @@ public interface ProductAttrConvert {
|
|||
|
||||
ProductAttrConvert INSTANCE = Mappers.getMapper(ProductAttrConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
ProductAttrPageDTO convert(ProductAttrPageRequest bean);
|
||||
|
||||
@Mappings({})
|
||||
PageResult<AdminsProductAttrPageResponse> convertPage(PageResult<ProductAttrWithValueBO> productAttrPage);
|
||||
|
||||
@Mappings({})
|
||||
List<AdminsProductAttrSimpleResponse> convertSimple(List<ProductAttrSimpleWithValueBO> simpleList);
|
||||
|
||||
@Mappings({})
|
||||
AdminsProdutAttrResponse convertAttr(ProductAttrBO attrBO);
|
||||
|
||||
@Mappings({})
|
||||
ProductAttrUpdateDTO convertUpdate(ProductAttrUpdateRequest updateRequest);
|
||||
|
||||
@Mappings({})
|
||||
AdminsProductAttrValueResponse convertAddResponse(ProductAttrValueBO result);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
package cn.iocoder.mall.product.rest.convert.brand;
|
||||
|
||||
import cn.iocoder.common.framework.vo.PageResult;
|
||||
import cn.iocoder.mall.product.biz.bo.brand.ProductBrandBO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandAddDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandPageDTO;
|
||||
import cn.iocoder.mall.product.biz.dto.brand.ProductBrandUpdateDTO;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandAddRequest;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandPageRequest;
|
||||
import cn.iocoder.mall.product.rest.request.brand.ProductBrandUpdateRequest;
|
||||
import cn.iocoder.mall.product.rest.response.brand.AdminsProductBrandResponse;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface ProductBrandConvert {
|
||||
|
||||
ProductBrandConvert INSTANCE = Mappers.getMapper(ProductBrandConvert.class);
|
||||
|
||||
@Mappings({})
|
||||
AdminsProductBrandResponse convert(ProductBrandBO brand);
|
||||
|
||||
@Mappings({})
|
||||
ProductBrandAddDTO convertAdd(ProductBrandAddRequest addRequest);
|
||||
|
||||
@Mappings({})
|
||||
ProductBrandUpdateDTO convertUpdate(ProductBrandUpdateRequest updateRequest);
|
||||
|
||||
@Mappings({})
|
||||
ProductBrandPageDTO convertPageRequest(ProductBrandPageRequest pageRequest);
|
||||
|
||||
@Mappings({})
|
||||
PageResult<AdminsProductBrandResponse> convertPage(PageResult<ProductBrandBO> productBrandPage);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package cn.iocoder.mall.product.rest.response.brand;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* VO
|
||||
*/
|
||||
@ApiModel(value = "商品品牌", description = "商品品牌")
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AdminsProductBrandResponse {
|
||||
/**
|
||||
* 规格编号
|
||||
*/
|
||||
@ApiModelProperty(value = "品牌编号", required = true, example = "1")
|
||||
private Integer id;
|
||||
|
||||
@ApiModelProperty(name = "name", value = "品牌名称", required = true, example = "安踏")
|
||||
@NotEmpty(message = "品牌名称不能为空")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(name = "description", value = "品牌描述", required = true, example = "安踏拖鞋")
|
||||
private String description;
|
||||
|
||||
@ApiModelProperty(name = "picUrl", value = "品牌图片", required = true, example = "http://www.iocoder.cn")
|
||||
private String picUrl;
|
||||
|
||||
@ApiModelProperty(name = "status", value = "状态 1开启 2禁用", required = true, example = "1")
|
||||
private Integer status;
|
||||
|
||||
}
|
|
@ -151,14 +151,4 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
return ProductSpuConvert.INSTANCE.convert3(skus, spus, attrAndValuePairList);
|
||||
}
|
||||
|
||||
private boolean sendProductUpdateMessage(Integer id) {
|
||||
// 创建 Message 对象
|
||||
ProductUpdateMessage message = new ProductUpdateMessage().setId(id);
|
||||
// 创建 Spring Message 对象
|
||||
Message<ProductUpdateMessage> springMessage = MessageBuilder.withPayload(message)
|
||||
.build();
|
||||
// 发送消息
|
||||
return mqStreamProducer.productUpdateOutput().send(springMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,8 +68,4 @@ public class AdminsProductSpuController {
|
|||
return success(ProductSpuConvert.INSTANCE.convert3(list));
|
||||
}
|
||||
|
||||
private <T> List<T> parseSkus(String skuStr, Class<T> clazz) {
|
||||
return JSON.parseArray(skuStr, clazz);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?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>onemall</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>search-service-project</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<modules>
|
||||
<module>search-service-api</module>
|
||||
<module>search-service-app</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- onemall 基础 bom 文件 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-dependencies</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 自身项目 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>search-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,31 @@
|
|||
<?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-service-project</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>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,80 @@
|
|||
<?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-service-project</artifactId>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>search-service-app</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<!-- RPC 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <!– 系统服务 –>-->
|
||||
<!-- <groupId>cn.iocoder.mall</groupId>-->
|
||||
<!-- <artifactId>system-service-api</artifactId>-->
|
||||
<!-- <version>${project.version}</version>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<dependency>
|
||||
<!-- 商品服务 -->
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>product-service-api</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MQ 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.mall</groupId>
|
||||
<artifactId>mall-spring-boot-starter-rocketmq</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Registry 和 Config 相关 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 工具类相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</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.aspectj</groupId>
|
||||
<artifactId>aspectjweaver</artifactId>
|
||||
<version>1.9.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,4 @@
|
|||
package cn.iocoder.mall.searchservice;
|
||||
|
||||
public class SearchServiceApplication {
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package cn.iocoder.mall.search.biz.config;
|
||||
package cn.iocoder.mall.searchservice.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages = "cn.iocoder.mall.search.biz.dao")
|
||||
public class JPAConfiguration {
|
||||
public class ElasticsearchConfiguration {
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package cn.iocoder.mall.search.biz.constant;
|
||||
package cn.iocoder.mall.searchservice.dal.es;
|
||||
|
||||
/**
|
||||
* ES 字段分析器的枚举类
|
|
@ -1,6 +1,6 @@
|
|||
package cn.iocoder.mall.search.biz.dataobject;
|
||||
package cn.iocoder.mall.searchservice.dal.es.dataobject;
|
||||
|
||||
import cn.iocoder.mall.search.biz.constant.FieldAnalyzer;
|
||||
import cn.iocoder.mall.searchservice.dal.es.FieldAnalyzer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.springframework.data.annotation.Id;
|
||||
|
@ -13,7 +13,7 @@ import java.util.List;
|
|||
/**
|
||||
* 商品 ES DO
|
||||
*/
|
||||
@Document(indexName = "product", type = "spu", shards = 1, replicas = 0)
|
||||
@Document(indexName = "product", type = "product", shards = 1, replicas = 0)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ESProductDO {
|
|
@ -1,9 +1,9 @@
|
|||
package cn.iocoder.mall.search.biz.dao;
|
||||
package cn.iocoder.mall.searchservice.dal.es.repository;
|
||||
|
||||
import cn.iocoder.common.framework.util.CollectionUtil;
|
||||
import cn.iocoder.common.framework.util.StringUtil;
|
||||
import cn.iocoder.common.framework.util.CollectionUtils;
|
||||
import cn.iocoder.common.framework.util.StringUtils;
|
||||
import cn.iocoder.common.framework.vo.SortingField;
|
||||
import cn.iocoder.mall.search.biz.dataobject.ESProductDO;
|
||||
import cn.iocoder.mall.searchservice.dal.es.dataobject.ESProductDO;
|
||||
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
|
||||
import org.elasticsearch.index.query.QueryBuilders;
|
||||
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
|
||||
|
@ -35,7 +35,7 @@ public interface ProductRepository extends ElasticsearchRepository<ESProductDO,
|
|||
nativeSearchQueryBuilder.withFilter(QueryBuilders.termQuery("cid", cid));
|
||||
}
|
||||
// 筛选
|
||||
if (StringUtil.hasText(keyword)) {
|
||||
if (StringUtils.hasText(keyword)) {
|
||||
FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = { // TODO 芋艿,分值随便打的
|
||||
new FunctionScoreQueryBuilder.FilterFunctionBuilder(matchQuery("name", keyword),
|
||||
ScoreFunctionBuilders.weightFactorFunction(10)),
|
||||
|
@ -54,10 +54,10 @@ public interface ProductRepository extends ElasticsearchRepository<ESProductDO,
|
|||
nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
|
||||
}
|
||||
// 排序
|
||||
if (!CollectionUtil.isEmpty(sortFields)) {
|
||||
if (!CollectionUtils.isEmpty(sortFields)) {
|
||||
sortFields.forEach(sortField -> nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortField.getField())
|
||||
.order(SortOrder.fromString(sortField.getOrder()))));
|
||||
} else if (StringUtil.hasText(keyword)) {
|
||||
} else if (StringUtils.hasText(keyword)) {
|
||||
nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC));
|
||||
} else {
|
||||
nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("sort").order(SortOrder.DESC));
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* 占位
|
||||
*/
|
||||
package cn.iocoder.mall.searchservice.manager;
|
|
@ -0,0 +1,40 @@
|
|||
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<ProductSpuRespDTO> productSpuResult = productSpuRpc.getProductSpu(id);
|
||||
productSpuResult.checkError();
|
||||
// 获得商品 SKU
|
||||
CommonResult<List<ProductSkuRespDTO>> listProductSkusResult =
|
||||
productSkuRpc.listProductSkus(new ProductSkuListQueryReqDTO().setProductSpuId(id));
|
||||
listProductSkusResult.checkError();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* 占位
|
||||
*/
|
||||
package cn.iocoder.mall.searchservice.service;
|
|
@ -0,0 +1,7 @@
|
|||
package cn.iocoder.mall.searchservice.service.product;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ProductSearchService {
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
spring:
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址
|
||||
namespace: dev # Nacos 命名空间
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
|
|
@ -0,0 +1,18 @@
|
|||
spring:
|
||||
# Spring Cloud 配置项
|
||||
cloud:
|
||||
nacos:
|
||||
# Spring Cloud Nacos Discovery 配置项
|
||||
discovery:
|
||||
server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址
|
||||
namespace: dev # Nacos 命名空间
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Dubbo 注册中心
|
||||
registry:
|
||||
# address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
|
||||
address: nacos://400-infra.server.iocoder.cn:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址
|
||||
# Dubbo 服务提供者的配置
|
||||
provider:
|
||||
tag: ${DUBBO_TAG} # Dubbo 路由分组
|
|
@ -0,0 +1,46 @@
|
|||
spring:
|
||||
# Application 的配置项
|
||||
application:
|
||||
name: search-service
|
||||
# Profile 的配置项
|
||||
profiles:
|
||||
active: local
|
||||
|
||||
# Dubbo 配置项
|
||||
dubbo:
|
||||
# Spring Cloud Alibaba Dubbo 专属配置
|
||||
cloud:
|
||||
subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用
|
||||
# Dubbo 提供者的协议
|
||||
protocol:
|
||||
name: dubbo
|
||||
port: -1
|
||||
# Dubbo 提供服务的扫描基础包
|
||||
scan:
|
||||
base-packages: cn.iocoder.mall.searrchservice.rpc
|
||||
# Dubbo 服务提供者的配置
|
||||
provider:
|
||||
filter: -exception
|
||||
validation: true # 开启 Provider 参数校验
|
||||
version: 1.0.0 # 服务的版本号
|
||||
# Dubbo 服务消费者的配置
|
||||
consumer:
|
||||
ErrorCodeRpc:
|
||||
version: 1.0.0
|
||||
ProductCategoryRpc:
|
||||
version: 1.0.0
|
||||
ProductSpuRpc:
|
||||
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
|
|
@ -46,13 +46,6 @@ public class ProductSearchServiceImpl implements ProductSearchService {
|
|||
@Autowired
|
||||
private ElasticsearchTemplate elasticsearchTemplate; // 因为需要使用到聚合操作,只好引入 ElasticsearchTemplate 。
|
||||
|
||||
@Reference(validation = "true", version = "${dubbo.consumer.ProductSpuService.version}")
|
||||
private ProductSpuService productSpuService;
|
||||
@Reference(validation = "true", version = "${dubbo.consumer.ProductCategoryService.version}")
|
||||
private ProductCategoryService productCategoryService;
|
||||
@Reference(validation = "true", version = "${dubbo.consumer.CartService.version}")
|
||||
private CartService cartService;
|
||||
|
||||
@Override
|
||||
public Integer rebuild() {
|
||||
// TODO 芋艿,因为目前商品比较少,所以写的很粗暴。等未来重构
|
||||
|
|
Loading…
Reference in New Issue