fix: 完善商品管理

This commit is contained in:
puhui999
2023-05-31 16:39:43 +08:00
parent 35daee84e7
commit e86214015d
15 changed files with 96 additions and 99 deletions

View File

@@ -1,7 +1,5 @@
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -12,6 +10,11 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品Spu导出 Request VO,参数和 ProductSpuPageReqVO 是一致的")
@Data
@NoArgsConstructor
@@ -22,7 +25,6 @@ public class ProductSpuExportReqVO {
private String name;
@Schema(description = "前端请求的tab类型", example = "1")
@InEnum(ProductSpuPageTabEnum.class)
private Integer tabType;
@Schema(description = "商品分类编号", example = "100")

View File

@@ -2,14 +2,12 @@ package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -25,11 +23,35 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
@ToString(callSuper = true)
public class ProductSpuPageReqVO extends PageParam {
/**
* 出售中商品
*/
public static final Integer FOR_SALE = 0;
/**
* 仓库中商品
*/
public static final Integer IN_WAREHOUSE = 1;
/**
* 已售空商品
*/
public static final Integer SOLD_OUT = 2;
/**
* 警戒库存
*/
public static final Integer ALERT_STOCK = 3;
/**
* 商品回收站
*/
public static final Integer RECYCLE_BIN = 4;
@Schema(description = "商品名称", example = "清凉小短袖")
private String name;
@Schema(description = "前端请求的tab类型", required = true, example = "1")
@InEnum(ProductSpuPageTabEnum.class)
private Integer tabType;
@Schema(description = "商品分类编号", example = "1")

View File

@@ -9,7 +9,7 @@ import java.time.LocalDateTime;
/**
* 商品 SPU Response VO
* TODO 移除ProductSpuPageRespVO相关应用跟换为ProductSpuRespVO已继承ProductSpuBaseVO 补全表格展示所需属性
*
* @author HUIHUI
*/
@Schema(description = "管理后台 - 商品 SPU Response VO")

View File

@@ -19,6 +19,16 @@ import lombok.*;
@NoArgsConstructor
@AllArgsConstructor
public class ProductCategoryDO extends BaseDO {
/**
* 父分类编号 - 根分类
*/
public static final Long PARENT_ID_NULL = 0L;
/**
* 限定分类层级
*/
public static final int CATEGORY_LEVEL = 2;
/**
* 分类编号
*/

View File

@@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReq
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.enums.ProductConstants;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
@@ -119,25 +118,25 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
*/
static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> queryWrapper) {
// 出售中商品
if (ObjectUtil.equals(ProductSpuPageTabEnum.FOR_SALE.getType(), tabType)) {
if (ObjectUtil.equals(ProductSpuPageReqVO.FOR_SALE, tabType)) {
queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus());
}
// 仓储中商品
if (ObjectUtil.equals(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), tabType)) {
if (ObjectUtil.equals(ProductSpuPageReqVO.IN_WAREHOUSE, tabType)) {
queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus());
}
// 已售空商品
if (ObjectUtil.equals(ProductSpuPageTabEnum.SOLD_OUT.getType(), tabType)) {
if (ObjectUtil.equals(ProductSpuPageReqVO.SOLD_OUT, tabType)) {
queryWrapper.eqIfPresent(ProductSpuDO::getStock, 0);
}
// 警戒库存
if (ObjectUtil.equals(ProductSpuPageTabEnum.ALERT_STOCK.getType(), tabType)) {
if (ObjectUtil.equals(ProductSpuPageReqVO.ALERT_STOCK, tabType)) {
queryWrapper.le(ProductSpuDO::getStock, ProductConstants.ALERT_STOCK)
// 如果库存触发警戒库存且状态为回收站的话则不在警戒库存列表展示
.notIn(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
}
// 回收站
if (ObjectUtil.equals(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), tabType)) {
if (ObjectUtil.equals(ProductSpuPageReqVO.RECYCLE_BIN, tabType)) {
queryWrapper.eqIfPresent(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus());
}
}

View File

@@ -16,6 +16,7 @@ import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.PARENT_ID_NULL;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
/**
@@ -69,7 +70,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
private void validateParentProductCategory(Long id) {
// 如果是根分类,无需验证
if (Objects.equals(id, ProductConstants.PARENT_ID_NULL)) {
if (Objects.equals(id, PARENT_ID_NULL)) {
return;
}
// 父分类不存在
@@ -78,7 +79,7 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
throw exception(CATEGORY_PARENT_NOT_EXISTS);
}
// 父分类不能是二级分类
if (!Objects.equals(category.getParentId(), ProductConstants.PARENT_ID_NULL)) {
if (!Objects.equals(category.getParentId(), PARENT_ID_NULL)) {
throw exception(CATEGORY_PARENT_NOT_FIRST_LEVEL);
}
}
@@ -108,17 +109,16 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
@Override
public Integer getCategoryLevel(Long id) {
if (Objects.equals(id, ProductConstants.PARENT_ID_NULL)) {
if (Objects.equals(id, PARENT_ID_NULL)) {
return 0;
}
// TODO @puhui999for 的原因,是因为避免脏数据,导致可能的死循环。一般不会超过 100 层哈
int level = 1;
// fix: 循环次数不确定改为while循环
while (true){
// for 的原因,是因为避免脏数据,导致可能的死循环。一般不会超过 100 层哈
for (int i = 0; i < 100; i++) {
ProductCategoryDO category = productCategoryMapper.selectById(id);
// 如果没有父节点break 结束
if (category == null
|| Objects.equals(category.getParentId(), ProductConstants.PARENT_ID_NULL)) {
|| Objects.equals(category.getParentId(), PARENT_ID_NULL)) {
break;
}
// 继续递归父节点

View File

@@ -14,7 +14,6 @@ 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.ProductConstants;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuPageTabEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
@@ -29,6 +28,7 @@ import java.util.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.CATEGORY_LEVEL;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.*;
/**
@@ -129,7 +129,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
private void validateCategory(Long id) {
categoryService.validateCategory(id);
// 校验层级
if (categoryService.getCategoryLevel(id) != ProductConstants.CATEGORY_LEVEL) {
if (categoryService.getCategoryLevel(id) < CATEGORY_LEVEL) {
throw exception(SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR);
}
}
@@ -237,17 +237,17 @@ public class ProductSpuServiceImpl implements ProductSpuService {
@Override
public Map<Integer, Long> getTabsCount() {
Map<Integer, Long> counts = new HashMap<>(ProductConstants.SPU_TAB_COUNTS);
Map<Integer, Long> counts = new HashMap<>(5);
// 查询销售中的商品数量
counts.put(ProductSpuPageTabEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()));
counts.put(ProductSpuPageReqVO.FOR_SALE, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()));
// 查询仓库中的商品数量
counts.put(ProductSpuPageTabEnum.IN_WAREHOUSE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()));
counts.put(ProductSpuPageReqVO.IN_WAREHOUSE, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.DISABLE.getStatus()));
// 查询售空的商品数量
counts.put(ProductSpuPageTabEnum.SOLD_OUT.getType(), productSpuMapper.selectCount(ProductSpuDO::getStock, 0));
counts.put(ProductSpuPageReqVO.SOLD_OUT, productSpuMapper.selectCount(ProductSpuDO::getStock, 0));
// 查询触发警戒库存的商品数量
counts.put(ProductSpuPageTabEnum.ALERT_STOCK.getType(), productSpuMapper.selectCount());
counts.put(ProductSpuPageReqVO.ALERT_STOCK, productSpuMapper.selectCount());
// 查询回收站中的商品数量
counts.put(ProductSpuPageTabEnum.RECYCLE_BIN.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
counts.put(ProductSpuPageReqVO.RECYCLE_BIN, productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
return counts;
}

View File

@@ -18,9 +18,8 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEq
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.PARENT_ID_NULL;
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS;
import static cn.iocoder.yudao.module.product.enums.ProductConstants.PARENT_ID_NULL;
import static org.junit.jupiter.api.Assertions.*;
/**

View File

@@ -14,7 +14,6 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuUpdateR
import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
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.ProductSpuPageTabEnum;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.product.service.brand.ProductBrandServiceImpl;
import cn.iocoder.yudao.module.product.service.category.ProductCategoryServiceImpl;
@@ -318,7 +317,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
productSpuMapper.insertBatch(createReqVOs);
// 调用
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType());
productSpuPageReqVO.setTabType(ProductSpuPageReqVO.ALERT_STOCK);
PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
@@ -366,7 +365,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
productSpuMapper.insertBatch(createReqVOs);
// 调用
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType());
productSpuPageReqVO.setTabType(ProductSpuPageReqVO.ALERT_STOCK);
PageResult<ProductSpuDO> spuPage = productSpuService.getSpuPage(productSpuPageReqVO);
assertEquals(createReqVOs.size(), spuPage.getTotal());
}
@@ -407,11 +406,11 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
// 调用
ProductSpuPageReqVO productSpuPageReqVO = new ProductSpuPageReqVO();
// 查询条件 按需打开
//productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.ALERT_STOCK.getType());
//productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.RECYCLE_BIN.getType());
//productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.FOR_SALE.getType());
//productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.IN_WAREHOUSE.getType());
//productSpuPageReqVO.setTabType(ProductSpuPageTabEnum.SOLD_OUT.getType());
//productSpuPageReqVO.setTabType(ProductSpuPageReqVO.ALERT_STOCK);
//productSpuPageReqVO.setTabType(ProductSpuPageReqVO.RECYCLE_BIN);
//productSpuPageReqVO.setTabType(ProductSpuPageReqVO.FOR_SALE);
//productSpuPageReqVO.setTabType(ProductSpuPageReqVO.IN_WAREHOUSE);
//productSpuPageReqVO.setTabType(ProductSpuPageReqVO.SOLD_OUT);
//productSpuPageReqVO.setName(createReqVO.getName());
//productSpuPageReqVO.setCategoryId(createReqVO.getCategoryId());