mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-16 11:11:53 +08:00
product:优化管理后台相关的接口
area:增加地区列表界面
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
package cn.iocoder.yudao.module.product.controller.admin.property.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO 芋艿:看看怎么删除
|
||||
@ApiModel("管理后台 - 商品属性详情展示 Request VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class ProductPropertyViewRespVO {
|
||||
|
||||
@ApiModelProperty(value = "属性项 id", example = "1")
|
||||
public Long propertyId;
|
||||
|
||||
@ApiModelProperty(value = "属性项的名字", example = "内存")
|
||||
public String name;
|
||||
|
||||
@ApiModelProperty(value = "属性值数组")
|
||||
public List<Tuple2> propertyValues;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "属性值元组")
|
||||
public static class Tuple2 {
|
||||
private final long id;
|
||||
private final String name;
|
||||
|
||||
public Tuple2(Long id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package cn.iocoder.yudao.module.product.controller.admin.property.vo.value;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@ApiModel("管理后台 - 商品属性值的明细 Response VO")
|
||||
@Data
|
||||
public class ProductPropertyValueDetailRespVO {
|
||||
|
||||
@ApiModelProperty(value = "属性的编号", required = true, example = "1")
|
||||
private Long propertyId;
|
||||
|
||||
@ApiModelProperty(value = "属性的名称", required = true, example = "颜色")
|
||||
private String propertyName;
|
||||
|
||||
@ApiModelProperty(value = "属性值的编号", required = true, example = "1024")
|
||||
private Long valueId;
|
||||
|
||||
@ApiModelProperty(value = "属性值的名称", required = true, example = "红色")
|
||||
private String valueName;
|
||||
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
### 获得商品 SPU 明细
|
||||
GET {{baseUrl}}/product/spu/get-detail?id=4
|
||||
Authorization: Bearer {{token}}
|
||||
tenant-id: {{adminTenentId}}
|
@@ -3,8 +3,13 @@ package cn.iocoder.yudao.module.product.controller.admin.spu;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
|
||||
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
|
||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
@@ -15,10 +20,11 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
|
||||
|
||||
@Api(tags = "管理后台 - 商品 SPU")
|
||||
@RestController
|
||||
@@ -28,6 +34,10 @@ public class ProductSpuController {
|
||||
|
||||
@Resource
|
||||
private ProductSpuService productSpuService;
|
||||
@Resource
|
||||
private ProductSkuService productSkuService;
|
||||
@Resource
|
||||
private ProductPropertyValueService productPropertyValueService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@ApiOperation("创建商品 SPU")
|
||||
@@ -53,31 +63,24 @@ public class ProductSpuController {
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// TODO 芋艿:修改接口
|
||||
@GetMapping("/get/detail")
|
||||
@ApiOperation("获得商品 SPU")
|
||||
@GetMapping("/get-detail")
|
||||
@ApiOperation("获得商品 SPU 明细")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('product:spu:query')")
|
||||
public CommonResult<ProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
|
||||
return success(productSpuService.getSpuDetail(id));
|
||||
}
|
||||
// 获得商品 SPU
|
||||
ProductSpuDO spu = productSpuService.getSpu(id);
|
||||
if (spu == null) {
|
||||
throw exception(SPU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@ApiOperation("获得商品 SPU")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('product:spu:query')")
|
||||
public CommonResult<ProductSpuDO> getSpu(@RequestParam("id") Long id) {
|
||||
return success(productSpuService.getSpu(id));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获得商品 SPU 列表")
|
||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
|
||||
@PreAuthorize("@ss.hasPermission('product:spu:query')")
|
||||
public CommonResult<List<ProductSpuDO>> getSpuList(@RequestParam("ids") Collection<Long> ids) {
|
||||
List<ProductSpuDO> list = productSpuService.getSpuList(ids);
|
||||
return success(ProductSpuConvert.INSTANCE.convertList(list));
|
||||
// 查询商品 SKU
|
||||
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuIdAndStatus(spu.getId(), null);
|
||||
// 查询商品属性
|
||||
List<ProductPropertyValueDetailRespBO> propertyValues = productPropertyValueService
|
||||
.getPropertyValueDetailList(ProductSkuConvert.INSTANCE.convertPropertyValueIds(skus));
|
||||
// 拼接
|
||||
return success(ProductSpuConvert.INSTANCE.convert03(spu, skus, propertyValues));
|
||||
}
|
||||
|
||||
@GetMapping("/get-simple-list")
|
||||
@@ -92,7 +95,7 @@ public class ProductSpuController {
|
||||
@ApiOperation("获得商品 SPU 分页")
|
||||
@PreAuthorize("@ss.hasPermission('product:spu:query')")
|
||||
public CommonResult<PageResult<ProductSpuRespVO>> getSpuPage(@Valid ProductSpuPageReqVO pageVO) {
|
||||
return success(productSpuService.getSpuPage(pageVO));
|
||||
return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,52 +1,27 @@
|
||||
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
|
||||
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel(value = "管理后台 - 商品 SPU 详细 Response VO", description = "包括关联的 SKU 等信息")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ProductSpuDetailRespVO extends ProductSpuBaseVO {
|
||||
|
||||
@ApiModelProperty(value = "主键", required = true, example = "1")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
public class ProductSpuDetailRespVO extends ProductSpuRespVO {
|
||||
|
||||
// ========== SKU 相关字段 =========
|
||||
|
||||
@ApiModelProperty(value = "库存", required = true, example = "true")
|
||||
private Integer totalStock;
|
||||
|
||||
@ApiModelProperty(value = " 最小价格,单位使用:分", required = true, example = "1024")
|
||||
private Integer minPrice;
|
||||
|
||||
@ApiModelProperty(value = "最大价格,单位使用:分", required = true, example = "1024")
|
||||
private Integer maxPrice;
|
||||
|
||||
@ApiModelProperty(value = "商品销量", example = "1024")
|
||||
private Integer salesCount;
|
||||
|
||||
/**
|
||||
* SKU 数组
|
||||
*/
|
||||
private List<Sku> skus;
|
||||
|
||||
// ========== 统计相关字段 =========
|
||||
|
||||
@ApiModelProperty(value = "点击量", example = "1024")
|
||||
private Integer clickCount;
|
||||
|
||||
@ApiModel(value = "管理后台 - 商品 SKU 详细 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@@ -56,29 +31,8 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO {
|
||||
/**
|
||||
* 属性数组
|
||||
*/
|
||||
private List<ProductSpuDetailRespVO.Property> properties;
|
||||
private List<ProductPropertyValueDetailRespVO> properties;
|
||||
|
||||
}
|
||||
|
||||
@ApiModel(value = "管理后台 - 商品属性的详细 Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public static class Property extends ProductSkuBaseVO.Property {
|
||||
|
||||
@ApiModelProperty(value = "属性项的名字", required = true, example = "颜色")
|
||||
private String propertyName;
|
||||
|
||||
@ApiModelProperty(value = "属性值的名称", required = true, example = "蓝色")
|
||||
private String valueName;
|
||||
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "分类 id 数组,一直递归到一级父节点", example = "4")
|
||||
private Long categoryId;
|
||||
|
||||
// TODO @芋艿:在瞅瞅~
|
||||
@ApiModelProperty(value = "属性修改和详情展示组合", example = "[{\"propertyId\":2,\"name\":\"内存\",\"propertyValues\":[{\"v1\":11,\"v2\":\"64G\"},{\"v1\":10,\"v2\":\"32G\"}]},{\"propertyId\":3,\"name\":\"尺寸\",\"propertyValues\":[{\"v1\":16,\"v2\":\"6.1\"},{\"v1\":15,\"v2\":\"5.7\"}]}]")
|
||||
private List<ProductPropertyViewRespVO> productPropertyViews;
|
||||
|
||||
}
|
||||
|
@@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
@@ -48,7 +48,7 @@ public class AppProductSpuController {
|
||||
|
||||
@GetMapping("/page")
|
||||
@ApiOperation("获得商品 SPU 分页")
|
||||
public CommonResult<PageResult<AppSpuPageItemRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
|
||||
public CommonResult<PageResult<AppProductSpuPageItemRespVO>> getSpuPage(@Valid AppProductSpuPageReqVO pageVO) {
|
||||
PageResult<ProductSpuDO> pageResult = productSpuService.getSpuPage(pageVO, ProductSpuStatusEnum.ENABLE.getStatus());
|
||||
return success(ProductSpuConvert.INSTANCE.convertPage02(pageResult));
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class AppProductSpuController {
|
||||
@GetMapping("/get-detail")
|
||||
@ApiOperation("获得商品 SPU 明细")
|
||||
@ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
|
||||
public CommonResult<AppSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
|
||||
public CommonResult<AppProductSpuDetailRespVO> getSpuDetail(@RequestParam("id") Long id) {
|
||||
// 获得商品 SPU
|
||||
ProductSpuDO spu = productSpuService.getSpu(id);
|
||||
if (spu == null) {
|
||||
|
@@ -9,7 +9,7 @@ import java.util.List;
|
||||
|
||||
@ApiModel("用户 App - 商品 SPU 明细 Response VO")
|
||||
@Data
|
||||
public class AppSpuDetailRespVO {
|
||||
public class AppProductSpuDetailRespVO {
|
||||
|
||||
@ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
|
||||
private Long id;
|
@@ -10,7 +10,7 @@ import java.util.List;
|
||||
|
||||
@ApiModel("用户 App - 商品 SPU 分页项 Response VO")
|
||||
@Data
|
||||
public class AppSpuPageItemRespVO {
|
||||
public class AppProductSpuPageItemRespVO {
|
||||
|
||||
@ApiModelProperty(value = "商品 SPU 编号", required = true, example = "1")
|
||||
private Long id;
|
@@ -3,11 +3,12 @@ package cn.iocoder.yudao.module.product.convert.spu;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||
import cn.iocoder.yudao.module.product.controller.app.property.vo.value.AppProductPropertyValueDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppSpuPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
|
||||
@@ -45,9 +46,9 @@ public interface ProductSpuConvert {
|
||||
|
||||
List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
|
||||
|
||||
default AppSpuDetailRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus,
|
||||
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
||||
AppSpuDetailRespVO spuVO = convert02(spu)
|
||||
default AppProductSpuDetailRespVO convert(ProductSpuDO spu, List<ProductSkuDO> skus,
|
||||
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
||||
AppProductSpuDetailRespVO spuVO = convert02(spu)
|
||||
.setSalesCount(spu.getSalesCount() + defaultIfNull(spu.getVirtualSalesCount(), 0));
|
||||
spuVO.setSkus(convertList03(skus));
|
||||
// 处理商品属性
|
||||
@@ -57,7 +58,7 @@ public interface ProductSpuConvert {
|
||||
if (CollUtil.isEmpty(properties)) {
|
||||
continue;
|
||||
}
|
||||
AppSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
|
||||
AppProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
|
||||
sku.setProperties(new ArrayList<>(properties.size()));
|
||||
// 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中
|
||||
properties.forEach(property -> {
|
||||
@@ -70,10 +71,38 @@ public interface ProductSpuConvert {
|
||||
}
|
||||
return spuVO;
|
||||
}
|
||||
AppSpuDetailRespVO convert02(ProductSpuDO spu);
|
||||
List<AppSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> skus);
|
||||
AppProductSpuDetailRespVO convert02(ProductSpuDO spu);
|
||||
List<AppProductSpuDetailRespVO.Sku> convertList03(List<ProductSkuDO> skus);
|
||||
AppProductPropertyValueDetailRespVO convert03(ProductPropertyValueDetailRespBO propertyValue);
|
||||
|
||||
PageResult<AppSpuPageItemRespVO> convertPage02(PageResult<ProductSpuDO> page);
|
||||
PageResult<AppProductSpuPageItemRespVO> convertPage02(PageResult<ProductSpuDO> page);
|
||||
|
||||
default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus,
|
||||
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
||||
ProductSpuDetailRespVO spuVO = convert03(spu);
|
||||
spuVO.setSkus(convertList04(skus));
|
||||
// 处理商品属性
|
||||
Map<Long, ProductPropertyValueDetailRespBO> propertyValueMap = convertMap(propertyValues, ProductPropertyValueDetailRespBO::getValueId);
|
||||
for (int i = 0; i < skus.size(); i++) {
|
||||
List<ProductSkuDO.Property> properties = skus.get(i).getProperties();
|
||||
if (CollUtil.isEmpty(properties)) {
|
||||
continue;
|
||||
}
|
||||
ProductSpuDetailRespVO.Sku sku = spuVO.getSkus().get(i);
|
||||
sku.setProperties(new ArrayList<>(properties.size()));
|
||||
// 遍历每个 properties,设置到 AppSpuDetailRespVO.Sku 中
|
||||
properties.forEach(property -> {
|
||||
ProductPropertyValueDetailRespBO propertyValue = propertyValueMap.get(property.getValueId());
|
||||
if (propertyValue == null) {
|
||||
return;
|
||||
}
|
||||
sku.getProperties().add(convert04(propertyValue));
|
||||
});
|
||||
}
|
||||
return spuVO;
|
||||
}
|
||||
ProductSpuDetailRespVO convert03(ProductSpuDO spu);
|
||||
List<ProductSpuDetailRespVO.Sku> convertList04(List<ProductSkuDO> skus);
|
||||
ProductPropertyValueDetailRespVO convert04(ProductPropertyValueDetailRespBO propertyValue);
|
||||
|
||||
}
|
||||
|
@@ -21,8 +21,7 @@ public interface ProductPropertyMapper extends BaseMapperX<ProductPropertyDO> {
|
||||
}
|
||||
|
||||
default ProductPropertyDO selectByName(String name) {
|
||||
return selectOne(new LambdaQueryWrapperX<ProductPropertyDO>()
|
||||
.eqIfPresent(ProductPropertyDO::getName, name));
|
||||
return selectOne(ProductPropertyDO::getName, name);
|
||||
}
|
||||
|
||||
default List<ProductPropertyDO> selectList(ProductPropertyListReqVO listReqVO) {
|
||||
|
@@ -17,6 +17,7 @@ public interface ProductPropertyService {
|
||||
|
||||
/**
|
||||
* 创建属性项
|
||||
* 注意,如果已经存在该属性项,直接返回它的编号即可
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
|
@@ -40,9 +40,10 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createProperty(ProductPropertyCreateReqVO createReqVO) {
|
||||
// 校验名字重复
|
||||
if (productPropertyMapper.selectByName(createReqVO.getName()) != null) {
|
||||
throw exception(PROPERTY_EXISTS);
|
||||
// 如果已经添加过该属性项,直接返回
|
||||
ProductPropertyDO dbProperty = productPropertyMapper.selectByName(createReqVO.getName());
|
||||
if (dbProperty != null) {
|
||||
return dbProperty.getId();
|
||||
}
|
||||
|
||||
// 插入
|
||||
|
@@ -19,6 +19,7 @@ public interface ProductPropertyValueService {
|
||||
|
||||
/**
|
||||
* 创建属性值
|
||||
* 注意,如果已经存在该属性值,直接返回它的编号即可
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
|
@@ -42,9 +42,11 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ
|
||||
|
||||
@Override
|
||||
public Long createPropertyValue(ProductPropertyValueCreateReqVO createReqVO) {
|
||||
// 校验名字唯一
|
||||
if (productPropertyValueMapper.selectByName(createReqVO.getPropertyId(), createReqVO.getName()) != null) {
|
||||
throw exception(PROPERTY_VALUE_EXISTS);
|
||||
// 如果已经添加过该属性值,直接返回
|
||||
ProductPropertyValueDO dbValue = productPropertyValueMapper.selectByName(
|
||||
createReqVO.getPropertyId(), createReqVO.getName());
|
||||
if (dbValue != null) {
|
||||
return dbValue.getId();
|
||||
}
|
||||
|
||||
// 新增
|
||||
|
@@ -41,14 +41,6 @@ public interface ProductSpuService {
|
||||
*/
|
||||
void deleteSpu(Long id);
|
||||
|
||||
/**
|
||||
* 获得商品 SPU 详情
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 商品 SPU
|
||||
*/
|
||||
ProductSpuDetailRespVO getSpuDetail(Long id);
|
||||
|
||||
/**
|
||||
* 获得商品 SPU
|
||||
*
|
||||
@@ -88,7 +80,7 @@ public interface ProductSpuService {
|
||||
* @param pageReqVO 分页查询
|
||||
* @return 商品spu分页
|
||||
*/
|
||||
PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO);
|
||||
PageResult<ProductSpuDO> getSpuPage(ProductSpuPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 获得商品 SPU 分页
|
||||
|
@@ -1,27 +1,19 @@
|
||||
package cn.iocoder.yudao.module.product.service.spu;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.ProductPropertyViewRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
|
||||
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
|
||||
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
|
||||
import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
|
||||
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
||||
import cn.iocoder.yudao.module.product.service.property.ProductPropertyService;
|
||||
import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
|
||||
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -29,8 +21,10 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
@@ -49,18 +43,13 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
@Resource
|
||||
private ProductSpuMapper productSpuMapper;
|
||||
|
||||
@Resource
|
||||
private ProductCategoryService categoryService;
|
||||
|
||||
@Resource
|
||||
@Lazy // 循环依赖,避免报错
|
||||
private ProductSkuService productSkuService;
|
||||
@Resource
|
||||
private ProductPropertyService productPropertyService;
|
||||
@Resource
|
||||
private ProductPropertyValueService productPropertyValueService;
|
||||
@Resource
|
||||
private ProductBrandService brandService;
|
||||
@Resource
|
||||
private ProductCategoryService categoryService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -148,46 +137,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO @芋艿:需要再 review 下
|
||||
public ProductSpuDetailRespVO getSpuDetail(Long id) {
|
||||
ProductSpuDO spu = productSpuMapper.selectById(id);
|
||||
ProductSpuDetailRespVO respVO = BeanUtil.copyProperties(spu, ProductSpuDetailRespVO.class);
|
||||
if (null != spu) {
|
||||
List<ProductSpuDetailRespVO.Sku> skuReqs = ProductSkuConvert.INSTANCE.convertList03(productSkuService.getSkuListBySpuId(id));
|
||||
respVO.setSkus(skuReqs);
|
||||
// 组合 sku 属性
|
||||
if (spu.getSpecType().equals(ProductSpuSpecTypeEnum.DISABLE.getType())) {
|
||||
List<ProductSkuRespVO.Property> properties = new ArrayList<>();
|
||||
for (ProductSpuDetailRespVO.Sku productSkuRespVO : skuReqs) {
|
||||
properties.addAll(productSkuRespVO.getProperties());
|
||||
}
|
||||
Map<Long, List<ProductSkuBaseVO.Property>> propertyMaps = properties.stream().collect(Collectors.groupingBy(ProductSkuBaseVO.Property::getPropertyId));
|
||||
|
||||
List<ProductPropertyValueDO> propertyValueList = productPropertyValueService.getPropertyValueListByPropertyId(propertyMaps.keySet());
|
||||
List<ProductPropertyDO> propertyList = productPropertyService.getPropertyList(propertyMaps.keySet());
|
||||
// 装载组装过后的属性
|
||||
List<ProductPropertyViewRespVO> productPropertyViews = new ArrayList<>();
|
||||
propertyList.forEach(p -> {
|
||||
ProductPropertyViewRespVO productPropertyViewRespVO = new ProductPropertyViewRespVO();
|
||||
productPropertyViewRespVO.setPropertyId(p.getId());
|
||||
productPropertyViewRespVO.setName(p.getName());
|
||||
List<ProductPropertyViewRespVO.Tuple2> propertyValues = new ArrayList<>();
|
||||
// 转换成map是为了能快速获取
|
||||
Map<Long, ProductPropertyValueDO> propertyValueMaps = convertMap(propertyValueList, ProductPropertyValueDO::getId);
|
||||
propertyMaps.get(p.getId()).forEach(pv -> {
|
||||
ProductPropertyViewRespVO.Tuple2 tuple2 = new ProductPropertyViewRespVO.Tuple2(pv.getValueId(), propertyValueMaps.get(pv.getValueId()).getName());
|
||||
propertyValues.add(tuple2);
|
||||
});
|
||||
productPropertyViewRespVO.setPropertyValues(propertyValues.stream().distinct().collect(Collectors.toList()));
|
||||
productPropertyViews.add(productPropertyViewRespVO);
|
||||
});
|
||||
respVO.setProductPropertyViews(productPropertyViews);
|
||||
}
|
||||
}
|
||||
return respVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProductSpuDO getSpu(Long id) {
|
||||
return productSpuMapper.selectById(id);
|
||||
@@ -203,9 +152,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
return productSpuMapper.selectList();
|
||||
}
|
||||
|
||||
// TODO 芋艿:改成 DO 返回
|
||||
@Override
|
||||
public PageResult<ProductSpuRespVO> getSpuPage(ProductSpuPageReqVO pageReqVO) {
|
||||
public PageResult<ProductSpuDO> getSpuPage(ProductSpuPageReqVO pageReqVO) {
|
||||
// 库存告警的 SPU 编号的集合
|
||||
Set<Long> alarmStockSpuIds = null;
|
||||
if (Boolean.TRUE.equals(pageReqVO.getAlarmStock())) {
|
||||
@@ -215,7 +163,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
||||
}
|
||||
}
|
||||
// 分页查询
|
||||
return ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds));
|
||||
return productSpuMapper.selectPage(pageReqVO, alarmStockSpuIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -19,11 +19,12 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_STOCK_NOT_ENOUGH;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@@ -145,4 +146,26 @@ public class ProductSkuServiceTest extends BaseDbUnitTest {
|
||||
SKU_STOCK_NOT_ENOUGH);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSku_success() {
|
||||
// mock 数据
|
||||
ProductSkuDO dbSku = randomPojo(ProductSkuDO.class);
|
||||
productSkuMapper.insert(dbSku);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSku.getId();
|
||||
|
||||
// 调用
|
||||
productSkuService.deleteSku(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(productSkuMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSku_notExists() {
|
||||
// 准备参数
|
||||
Long id = 1L;
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> productSkuService.deleteSku(id), SKU_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
@@ -1,56 +0,0 @@
|
||||
package cn.iocoder.yudao.module.product.service.sku;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.dal.mysql.sku.ProductSkuMapper;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
// TODO 芋艿:整合到 {@link ProductSkuServiceTest} 中
|
||||
/**
|
||||
* {@link ProductSkuServiceImpl} 的单元测试类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Import(ProductSkuServiceImpl.class)
|
||||
@Disabled // TODO 芋艿:临时去掉
|
||||
public class SkuServiceImplTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
private ProductSkuServiceImpl ProductSkuService;
|
||||
|
||||
@Resource
|
||||
private ProductSkuMapper ProductSkuMapper;
|
||||
|
||||
@Test
|
||||
public void testDeleteSku_success() {
|
||||
// mock 数据
|
||||
ProductSkuDO dbSku = randomPojo(ProductSkuDO.class);
|
||||
ProductSkuMapper.insert(dbSku);// @Sql: 先插入出一条存在的数据
|
||||
// 准备参数
|
||||
Long id = dbSku.getId();
|
||||
|
||||
// 调用
|
||||
ProductSkuService.deleteSku(id);
|
||||
// 校验数据不存在了
|
||||
assertNull(ProductSkuMapper.selectById(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteSku_notExists() {
|
||||
// 准备参数
|
||||
Long id = 1L;
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> ProductSkuService.deleteSku(id), SKU_NOT_EXISTS);
|
||||
}
|
||||
|
||||
}
|
@@ -8,10 +8,11 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.property.ProductPropertyRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuCreateOrUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuCreateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
@@ -148,53 +149,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
||||
Assertions.assertNull(productSpuMapper.selectById(createReqVO.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpuDetail() {
|
||||
// 准备spu参数
|
||||
ProductSpuDO createReqVO = randomPojo(ProductSpuDO.class, o -> {
|
||||
o.setSpecType(ProductSpuSpecTypeEnum.DISABLE.getType());
|
||||
});
|
||||
productSpuMapper.insert(createReqVO);
|
||||
|
||||
// 创建两个属性
|
||||
ArrayList<ProductPropertyRespVO> productPropertyRespVOS = Lists.newArrayList(
|
||||
randomPojo(ProductPropertyRespVO.class),
|
||||
randomPojo(ProductPropertyRespVO.class));
|
||||
|
||||
// 所有属性值
|
||||
ArrayList<ProductPropertyValueRespVO> productPropertyValueRespVO = new ArrayList<>();
|
||||
|
||||
// 每个属性创建属性值
|
||||
productPropertyRespVOS.forEach(v -> {
|
||||
ProductPropertyValueRespVO productPropertyValueRespVO1 = randomPojo(ProductPropertyValueRespVO.class, o -> o.setPropertyId(v.getId()));
|
||||
productPropertyValueRespVO.add(productPropertyValueRespVO1);
|
||||
});
|
||||
|
||||
// 属性值建立笛卡尔积
|
||||
Map<Long, List<ProductPropertyValueRespVO>> collect = productPropertyValueRespVO.stream().collect(Collectors.groupingBy(ProductPropertyValueRespVO::getPropertyId));
|
||||
List<List<ProductPropertyValueRespVO>> lists = cartesianProduct(Lists.newArrayList(collect.values()));
|
||||
|
||||
// 准备sku参数
|
||||
ArrayList<ProductSkuDO> productSkuDOS = Lists.newArrayList();
|
||||
lists.forEach(pp -> {
|
||||
List<ProductSkuDO.Property> property = pp.stream().map(ppv -> new ProductSkuDO.Property(ppv.getPropertyId(), ppv.getId())).collect(Collectors.toList());
|
||||
ProductSkuDO productSkuDO = randomPojo(ProductSkuDO.class, o -> {
|
||||
o.setProperties(property);
|
||||
});
|
||||
productSkuDOS.add(productSkuDO);
|
||||
|
||||
});
|
||||
|
||||
Mockito.when(productSkuService.getSkuListBySpuId(createReqVO.getId())).thenReturn(productSkuDOS);
|
||||
// Mockito.when(productPropertyValueService.getPropertyValueListByPropertyId(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyValueRespVO);
|
||||
// Mockito.when(productPropertyService.getPropertyVOList(new ArrayList<>(collect.keySet()))).thenReturn(productPropertyRespVOS);
|
||||
//
|
||||
// 调用
|
||||
ProductSpuDetailRespVO spuDetail = productSpuService.getSpuDetail(createReqVO.getId());
|
||||
|
||||
assertPojoEquals(createReqVO, spuDetail);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getSpu() {
|
||||
// 准备参数
|
||||
@@ -222,7 +176,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
||||
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
|
||||
productSpuPageReqVO.setAlarmStock(true);
|
||||
|
||||
PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||
PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||
|
||||
PageResult<Object> result = PageResult.empty();
|
||||
Assertions.assertIterableEquals(result.getList(), spuPage.getList());
|
||||
@@ -271,7 +225,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
||||
// 调用
|
||||
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
|
||||
productSpuPageReqVO.setAlarmStock(true);
|
||||
PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||
PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||
|
||||
PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, alarmStockSpuIds));
|
||||
Assertions.assertIterableEquals(result.getList(), spuPage.getList());
|
||||
@@ -323,7 +277,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
||||
productSpuPageReqVO.setStatus(ProductSpuStatusEnum.ENABLE.getStatus());
|
||||
productSpuPageReqVO.setCategoryId(categoryId);
|
||||
|
||||
PageResult<ProductSpuRespVO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||
PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
|
||||
|
||||
PageResult<ProductSpuRespVO> result = ProductSpuConvert.INSTANCE.convertPage(productSpuMapper.selectPage(productSpuPageReqVO, (Set<Long>) null));
|
||||
assertEquals(result, spuPage);
|
||||
|
Reference in New Issue
Block a user