进行商品修改的迁移

This commit is contained in:
YunaiV
2020-07-28 20:10:03 +08:00
parent e107b42f53
commit 75876682fb
28 changed files with 337 additions and 759 deletions

View File

@@ -1,42 +0,0 @@
package cn.iocoder.mall.product.biz.bo.brand;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 商品品牌 VO
*/
@Data
@Accessors(chain = true)
public class ProductBrandBO implements Serializable {
/**
* 规格编号
*/
private Integer id;
/**
* 名称
*/
private String name;
/**
* 描述
*/
private String description;
/**
* 图片地址
*/
private String picUrl;
/**
* 状态
*
* 1-开启
* 2-禁用
*/
private Integer status;
}

View File

@@ -1,22 +0,0 @@
package cn.iocoder.mall.product.biz.dao.sku;
import cn.iocoder.mall.product.biz.dataobject.spu.ProductSkuDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductSkuMapper extends BaseMapper<ProductSkuDO> {
default List<ProductSkuDO> selectListBySpuIdAndStatus(Integer spuId, Integer status) {
return selectList(Wrappers.<ProductSkuDO>query().lambda()
.eq(ProductSkuDO::getSpuId, spuId)
.eq(ProductSkuDO::getStatus, status)
.eq(ProductSkuDO::getDeleted, false));
}
void insertList(@Param("productSkuDOs") List<ProductSkuDO> productSkuDOs);
}

View File

@@ -1,5 +0,0 @@
/**
* author: sin
* time: 2020/5/3 8:29 下午
*/
package cn.iocoder.mall.product.biz.dto;

View File

@@ -1,41 +0,0 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* 商品 Spu 分页 DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuPageDTO {
/**
* 商品名
*
* 模糊匹配
*/
private String name;
/**
* 分类编号
*/
private Integer cid;
/**
* 是否可见
*/
private Boolean visible;
/**
* 是否有库存
*
* 允许为空。空时,不进行筛选
*/
private Boolean hasQuantity;
@NotNull(message = "页码不能为空")
private Integer pageNo;
@NotNull(message = "每页条数不能为空")
private Integer pageSize;
}

View File

@@ -1,68 +0,0 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU + SKU 更新 DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuUpdateDTO {
/**
* Spu 编号
*/
@NotNull(message = "SPU 编号不能为空")
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotNull(message = "商品主图不能为空")
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
@NotNull(message = "是否上架不能为空")
private Boolean visible;
// ========== SKU =========
/**
* SKU 数组
*/
@NotNull(message = "SKU 不能为空")
private List<ProductSkuAddOrUpdateDTO> skus;
}

View File

@@ -1,35 +0,0 @@
package cn.iocoder.mall.product.biz.dto.product;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 更新商品收藏参数
* @author xiaofeng
* @date 2019/07/01 20:38
* @version 1.0
*/
@Data
@Accessors(chain = true)
public class UserProductSpuCollectionsUpdateDTO implements Serializable {
/**
* id自增长
*/
private Integer id;
/**
* 更新时间
*/
private Date updateTime;
/**
* 删除状态
*/
private Integer deleted;
}

View File

@@ -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);
}
}

View File

@@ -30,10 +30,6 @@ public interface ProductSpuService {
List<ProductSkuDetailBO> getProductSkuDetailList(Collection<Integer> ids);
ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO);
void updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO);
Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort);
}

View File

@@ -1,68 +0,0 @@
package cn.iocoder.mall.product.api.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 商品 SPU + SKU 更新 DTO
*/
@Data
@Accessors(chain = true)
public class ProductSpuUpdateDTO {
/**
* Spu 编号
*/
@NotNull(message = "SPU 编号不能为空")
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
@NotEmpty(message = "SPU 名字不能为空")
private String name;
/**
* 卖点
*/
@NotEmpty(message = "卖点不能为空")
private String sellPoint;
/**
* 描述
*/
@NotEmpty(message = "描述不能为空")
private String description;
/**
* 分类编号
*/
@NotNull(message = "分类不能为空")
private Integer cid;
/**
* 商品主图地址
*/
@NotNull(message = "商品主图不能为空")
private List<String> picUrls;
// ========== 其他信息 =========
/**
* 是否上架商品(是否可见)。
*
* true 为已上架
* false 为已下架
*/
@NotNull(message = "是否上架不能为空")
private Boolean visible;
// ========== SKU =========
/**
* SKU 数组
*/
@NotNull(message = "SKU 不能为空")
private List<ProductSkuAddOrUpdateDTO> skus;
}

View File

@@ -88,7 +88,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
@Override
public ProductSpuDetailBO addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO) {
ProductSpuDetailBO productSpuDetailBO = addProductSpu0(adminId, productSpuAddDTO);
// 如果新增生成,发送创建商品 Topic 消息
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
sendProductUpdateMessage(productSpuDetailBO.getId());
@@ -96,76 +95,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
return productSpuDetailBO;
}
@Override
public void updateProductSpu(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
// 更新商品
updateProductSpu0(adminId, productSpuUpdateDTO);
// TODO 芋艿,先不考虑事务的问题。等后面的 fescar 一起搞
sendProductUpdateMessage(productSpuUpdateDTO.getId());
}
@SuppressWarnings("Duplicates")
@Transactional
public void updateProductSpu0(Integer adminId, ProductSpuUpdateDTO productSpuUpdateDTO) {
// 校验 Spu 是否存在
if (productSpuMapper.selectById(productSpuUpdateDTO.getId()) == null) {
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_NOT_EXISTS.getCode());
}
// 校验商品分类分类存在
ProductCategoryDO category = productCategoryService.validProductCategory(productSpuUpdateDTO.getCid());
if (ProductCategoryConstants.PID_ROOT.equals(category.getPid())) { // 商品只能添加到二级分类下
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEVEL2.getCode());
}
// 校验规格是否存在
Set<Integer> productAttrValueIds = new HashSet<>();
productSpuUpdateDTO.getSkus().forEach(productSkuAddDTO -> productAttrValueIds.addAll(productSkuAddDTO.getAttrs()));
List<ProductAttrAndValuePairBO> attrAndValuePairList = productAttrService.validProductAttrAndValue(productAttrValueIds,
true); // 读取规格时,需要考虑规格是否被禁用
// 校验 Sku 规格
validProductSku(productSpuUpdateDTO.getSkus(), attrAndValuePairList);
// 更新 Spu
ProductSpuDO updateSpu = ProductSpuConvert.INSTANCE.convert(productSpuUpdateDTO)
.setPicUrls(StringUtil.join(productSpuUpdateDTO.getPicUrls(), ","));
initSpuFromSkus(updateSpu, productSpuUpdateDTO.getSkus()); // 初始化 sku 相关信息到 spu 中
productSpuMapper.update(updateSpu);
// 修改 Sku
List<ProductSkuDO> existsSkus = productSkuMapper.selectListBySpuIdAndStatus(productSpuUpdateDTO.getId(), ProductSpuConstants.SKU_STATUS_ENABLE);
List<ProductSkuDO> insertSkus = new ArrayList<>(0); // 1、找不到进行插入
List<Integer> deleteSkus = new ArrayList<>(0); // 2、多余的删除
List<ProductSkuDO> updateSkus = new ArrayList<>(0); // 3、找的到进行更新。
for (ProductSkuAddOrUpdateDTO skuUpdateDTO : productSpuUpdateDTO.getSkus()) {
ProductSkuDO existsSku = findProductSku(skuUpdateDTO.getAttrs(), existsSkus);
// 3、找的到进行更新。
if (existsSku != null) {
// 移除
existsSkus.remove(existsSku);
// 创建 ProductSkuDO
updateSkus.add(ProductSpuConvert.INSTANCE.convert(skuUpdateDTO).setId(existsSku.getId()));
continue;
}
// 1、找不到进行插入
ProductSkuDO insertSku = ProductSpuConvert.INSTANCE.convert(skuUpdateDTO)
.setSpuId(productSpuUpdateDTO.getId()).setStatus(ProductSpuConstants.SKU_STATUS_ENABLE).setAttrs(StringUtil.join(skuUpdateDTO.getAttrs(), ","));
insertSku.setCreateTime(new Date());
insertSku.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
insertSkus.add(insertSku);
}
// 2、多余的删除
if (!existsSkus.isEmpty()) {
deleteSkus.addAll(existsSkus.stream().map(ProductSkuDO::getId).collect(Collectors.toList()));
}
// 执行修改 Sku
if (!insertSkus.isEmpty()) {
productSkuMapper.insertList(insertSkus);
}
if (!updateSkus.isEmpty()) {
updateSkus.forEach(productSkuDO -> productSkuMapper.update(productSkuDO));
}
if (!deleteSkus.isEmpty()) {
productSkuMapper.updateToDeleted(deleteSkus);
}
}
@Override
public Boolean updateProductSpuSort(Integer adminId, Integer spuId, Integer sort) {
// 校验 Spu 是否存在
@@ -181,21 +110,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
return true;
}
@Override
public ProductSpuPageBO getProductSpuPage(ProductSpuPageDTO productSpuPageDTO) {
ProductSpuPageBO productSpuPage = new ProductSpuPageBO();
// 查询分页数据
int offset = (productSpuPageDTO.getPageNo() - 1) * productSpuPageDTO.getPageSize();
productSpuPage.setList(ProductSpuConvert.INSTANCE.convert(productSpuMapper.selectListByNameLikeOrderBySortAsc(
productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getHasQuantity(), productSpuPageDTO.getVisible(),
offset, productSpuPageDTO.getPageSize())));
// 查询分页总数
productSpuPage.setTotal(productSpuMapper.selectCountByNameLike(productSpuPageDTO.getName(), productSpuPageDTO.getCid(), productSpuPageDTO.getHasQuantity(),
productSpuPageDTO.getVisible()));
// 返回结果
return productSpuPage;
}
@Override
public List<ProductSpuBO> getProductSpuSearchList(ProductSpuSearchListDTO productSpuSearchListDTO) {
return ProductSpuConvert.INSTANCE.convert(
@@ -237,28 +151,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
return ProductSpuConvert.INSTANCE.convert3(skus, spus, attrAndValuePairList);
}
/**
* 获得 sku 数组中,指定规格的 sku
*
* @param attrs 指定规格
* @param skus sku 数组
* @return 符合条件的 sku
*/
private ProductSkuDO findProductSku(Collection<Integer> attrs, List<ProductSkuDO> skus) {
if (CollectionUtil.isEmpty(skus)) {
return null;
}
// 创建成 Set ,方便后面比较
attrs = new HashSet<>(attrs);
for (ProductSkuDO sku : skus) {
Set<Integer> skuAttrs = StringUtil.split(sku.getAttrs(), ",").stream().map(Integer::parseInt).collect(Collectors.toSet());
if (attrs.equals(skuAttrs)) {
return sku;
}
}
return null;
}
private boolean sendProductUpdateMessage(Integer id) {
// 创建 Message 对象
ProductUpdateMessage message = new ProductUpdateMessage().setId(id);