REVIEW 商品管理的逻辑
This commit is contained in:
parent
7345d80b53
commit
cd86620b74
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.product.enums.spu;
|
|||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
// TODO @puhui999:中英文之间要有空格; 商品 spu Tab 标签枚举;这个类可以改成 ProductSpuPageTabEnum 会更好一点哈;分页 Tab 的意思;
|
||||
/**
|
||||
* 商品spu标签枚举类型
|
||||
*
|
||||
|
@ -11,11 +12,13 @@ import lombok.Getter;
|
|||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProductSpuTabTypeEnum {
|
||||
|
||||
FOR_SALE(0,"出售中商品"),
|
||||
IN_WAREHOUSE(1,"仓库中商品"),
|
||||
SOLD_OUT(2,"已售空商品"),
|
||||
ALERT_STOCK(3,"警戒库存"),
|
||||
RECYCLE_BIN(4,"商品回收站");
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
|
@ -24,4 +27,5 @@ public enum ProductSpuTabTypeEnum {
|
|||
* 状态名
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import lombok.Getter;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
// TODO @puhui999:是不是放到数据字典里?
|
||||
/**
|
||||
* 产品单位枚举
|
||||
*
|
||||
|
@ -14,6 +15,7 @@ import java.util.Arrays;
|
|||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ProductUnitEnum implements IntArrayValuable {
|
||||
|
||||
PIECE(1, "个"),
|
||||
DOZEN(2, "打"),
|
||||
BOX(3, "盒"),
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
|
||||
</dependency>
|
||||
<!-- TODO 芋艿:是不是可以去掉这个依赖呀? -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
|
||||
|
|
|
@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueServ
|
|||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import oracle.jdbc.proxy.annotation.Post;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -85,7 +84,8 @@ public class ProductPropertyController {
|
|||
@PostMapping("/get-value-list")
|
||||
@Operation(summary = "获得属性项列表")
|
||||
@PreAuthorize("@ss.hasPermission('product:property:query')")
|
||||
public CommonResult<List<ProductPropertyAndValueRespVO>> getPropertyAndValueList(@Valid @RequestBody ProductPropertyListReqVO listReqVO) {
|
||||
public CommonResult<List<ProductPropertyAndValueRespVO>> getPropertyAndValueList(
|
||||
@Valid @RequestBody ProductPropertyListReqVO listReqVO) {
|
||||
// 查询属性项
|
||||
List<ProductPropertyDO> keys = productPropertyService.getPropertyList(listReqVO);
|
||||
if (CollUtil.isEmpty(keys)) {
|
||||
|
|
|
@ -4,7 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 属性项 List Request VO")
|
||||
|
@ -15,6 +14,8 @@ public class ProductPropertyListReqVO {
|
|||
@Schema(description = "属性名称", example = "颜色")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "属性ids", example = "1,2")
|
||||
// TODO @puhui999:这个查询条件的作用是啥呀?
|
||||
@Schema(description = "属性编号的数组", example = "1,2")
|
||||
private List<Long> propertyIds;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.sku.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
@ -50,6 +46,7 @@ public class ProductSkuBaseVO {
|
|||
|
||||
@Schema(description = "商品体积", example = "1024") // 单位:m^3 平米
|
||||
private Double volume;
|
||||
// TODO @pitui999:注释可以去掉,VO 使用 @Schema 作为注释
|
||||
/**
|
||||
* 一级分销的佣金,单位:分
|
||||
*/
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class ProductSkuCreateOrUpdateReqVO extends ProductSkuBaseVO {
|
||||
|
||||
@Schema(description = "商品属性")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
|
|
|
@ -4,12 +4,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||
import lombok.*;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Schema(description = "管理后台 - 商品 SKU Response VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
@ -29,13 +25,17 @@ public class ProductSkuRespVO extends ProductSkuBaseVO {
|
|||
@NotNull(message = "属性编号不能为空")
|
||||
private Long propertyId;
|
||||
|
||||
// TODO @puhui999:propertyName 是不是也返回下
|
||||
|
||||
@Schema(description = "属性值编号", required = true, example = "1024")
|
||||
@NotNull(message = "属性值编号不能为空")
|
||||
private Long valueId;
|
||||
|
||||
@Schema(description = "属性值", example = "1024")
|
||||
private String valueName;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 属性数组
|
||||
*/
|
||||
|
|
|
@ -3,12 +3,9 @@ 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.v3.oas.annotations.Operation;
|
||||
|
@ -23,9 +20,7 @@ import javax.validation.Valid;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
|
||||
@Tag(name = "管理后台 - 商品 SPU")
|
||||
@RestController
|
||||
|
@ -94,6 +89,8 @@ public class ProductSpuController {
|
|||
public CommonResult<PageResult<ProductSpuPageRespVO>> getSpuPage(@Valid ProductSpuPageReqVO pageVO) {
|
||||
return success(ProductSpuConvert.INSTANCE.convertPage(productSpuService.getSpuPage(pageVO)));
|
||||
}
|
||||
|
||||
// TODO @tuihui999:get-count;另外,url 使用 - 拆分
|
||||
@GetMapping("/tabsCount")
|
||||
@Operation(summary = "获得商品 SPU tabsCount")
|
||||
@PreAuthorize("@ss.hasPermission('product:spu:query')")
|
||||
|
|
|
@ -1,13 +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.dal.dataobject.brand.ProductBrandDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.delivery.DeliveryTemplateDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
|
||||
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
|
@ -116,5 +108,4 @@ public class ProductSpuBaseVO {
|
|||
@Schema(description = "虚拟销量", required = true, example = "芋道")
|
||||
private Integer virtualSalesCount;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
|
||||
|
||||
import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueDetailRespVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuBaseVO;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.sku.vo.ProductSkuRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Schema(description = "管理后台 - 商品 SPU 详细 Response VO") // 包括关联的 SKU 等信息
|
||||
|
@ -19,6 +16,7 @@ public class ProductSpuDetailRespVO extends ProductSpuBaseVO {
|
|||
|
||||
@Schema(description = "商品编号", example = "1")
|
||||
private Long id;
|
||||
|
||||
// ========== SKU 相关字段 =========
|
||||
|
||||
@Schema(description = "SKU 数组", example = "1")
|
||||
|
|
|
@ -20,6 +20,7 @@ public class ProductSpuPageReqVO extends PageParam {
|
|||
@Schema(description = "商品名称", example = "yutou")
|
||||
private String name;
|
||||
|
||||
// TODO @puhui999:加下 @InEnum 校验
|
||||
@Schema(description = "前端请求的tab类型", example = "1")
|
||||
private Integer tabType;
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package cn.iocoder.yudao.module.product.controller.admin.spu.vo;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// TODO @puhui999:可以直接继承 ProductSpuRespVO 么?一般情况下,多返回一些字段问题不大的;另外,是不是使用 ProductSpuRespVO 替代
|
||||
@Schema(description = "管理后台 - 商品 SPU 分页 response VO")
|
||||
@Data
|
||||
public class ProductSpuPageRespVO {
|
||||
|
||||
@Schema(description = "spuId", example = "1")
|
||||
private Long id;
|
||||
@Schema(description = "商品封面图", example = "1")
|
||||
|
@ -28,4 +28,5 @@ public class ProductSpuPageRespVO {
|
|||
private LocalDateTime createTime;
|
||||
@Schema(description = "商品状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public interface ProductSpuConvert {
|
|||
|
||||
List<ProductSpuSimpleRespVO> convertList02(List<ProductSpuDO> list);
|
||||
|
||||
|
||||
// TODO @puhui999:是不是可以删除啦
|
||||
default ProductSpuDetailRespVO convert03(ProductSpuDO spu, List<ProductSkuDO> skus,
|
||||
List<ProductPropertyValueDetailRespBO> propertyValues) {
|
||||
ProductSpuDetailRespVO spuVO = convert03(spu);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package cn.iocoder.yudao.module.product.dal.dataobject.property;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
|
@ -20,7 +19,7 @@ import lombok.*;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ProductPropertyDO extends TenantBaseDO {
|
||||
public class ProductPropertyDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了?
|
||||
|
||||
/**
|
||||
* 主键
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package cn.iocoder.yudao.module.product.dal.dataobject.property;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
|
@ -21,7 +20,7 @@ import lombok.*;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ProductPropertyValueDO extends TenantBaseDO {
|
||||
public class ProductPropertyValueDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了?
|
||||
|
||||
/**
|
||||
* 主键
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package cn.iocoder.yudao.module.product.dal.dataobject.sku;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
|
||||
|
@ -28,7 +27,7 @@ import java.util.List;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ProductSkuDO extends TenantBaseDO {
|
||||
public class ProductSkuDO extends TenantBaseDO { // TODO @puhui999:这里是不是用 BaseDO 就可以了?
|
||||
|
||||
/**
|
||||
* 商品 SKU 编号,自增
|
||||
|
@ -116,7 +115,7 @@ public class ProductSkuDO extends TenantBaseDO {
|
|||
// * 冗余 {@link ProductPropertyDO#getName()}
|
||||
// *
|
||||
// * 注意:每次属性名字发生变化时,需要更新该冗余
|
||||
// */ TODO 与已有代码逻辑存在冲突
|
||||
// */ TODO @puhui999:与已有代码逻辑存在冲突;芋艿:冲突点是啥呀?
|
||||
//private String propertyName;
|
||||
|
||||
/**
|
||||
|
@ -131,7 +130,7 @@ public class ProductSkuDO extends TenantBaseDO {
|
|||
// * 冗余 {@link ProductPropertyValueDO#getName()}
|
||||
// *
|
||||
// * 注意:每次属性值名字发生变化时,需要更新该冗余
|
||||
// */ TODO 与已有代码逻辑存在冲突
|
||||
// */ TODO @puhui999:与已有代码逻辑存在冲突;芋艿:冲突点是啥呀?
|
||||
//private String valueName;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package cn.iocoder.yudao.module.product.dal.mysql.spu;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
||||
import cn.iocoder.yudao.module.product.controller.admin.spu.vo.ProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.controller.app.spu.vo.AppProductSpuPageReqVO;
|
||||
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
|
||||
|
@ -14,24 +12,14 @@ import cn.iocoder.yudao.module.product.enums.spu.ProductSpuTabTypeEnum;
|
|||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 商品spu Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
|
||||
|
||||
//default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO) {
|
||||
// return selectPage(reqVO, new LambdaQueryWrapperX<ProductSpuDO>()
|
||||
// .likeIfPresent(ProductSpuDO::getName, reqVO.getName())
|
||||
// .orderByDesc(ProductSpuDO::getSort));
|
||||
//}
|
||||
default PageResult<ProductSpuDO> selectPage(ProductSpuPageReqVO reqVO) {
|
||||
// TODO @puhui999:多个 tab,写 if else 去补条件,可阅读性会好点哈
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<ProductSpuDO>()
|
||||
// 商品名称
|
||||
.likeIfPresent(ProductSpuDO::getName, reqVO.getName())
|
||||
|
@ -42,7 +30,7 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
|
|||
.eq(ProductSpuTabTypeEnum.IN_WAREHOUSE.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.DISABLE.getStatus())
|
||||
// 已售空商品
|
||||
.eq(ProductSpuTabTypeEnum.SOLD_OUT.getType().equals(reqVO.getTabType()),ProductSpuDO::getStock,0)
|
||||
// TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换
|
||||
// TODO @phuui999:警戒库存暂时为 10,后期需要使用常量或者数据库配置替换
|
||||
.le(ProductSpuTabTypeEnum.ALERT_STOCK.getType().equals(reqVO.getTabType()),ProductSpuDO::getStock,10)
|
||||
// 回收站
|
||||
.eq(ProductSpuTabTypeEnum.RECYCLE_BIN.getType().equals(reqVO.getTabType()),ProductSpuDO::getStatus,ProductSpuStatusEnum.RECYCLE.getStatus())
|
||||
|
|
|
@ -40,6 +40,7 @@ public interface ProductPropertyService {
|
|||
|
||||
/**
|
||||
* 获得属性项列表
|
||||
*
|
||||
* @param listReqVO 集合查询
|
||||
* @return 属性项集合
|
||||
*/
|
||||
|
|
|
@ -94,7 +94,7 @@ public class ProductPropertyServiceImpl implements ProductPropertyService {
|
|||
|
||||
@Override
|
||||
public List<ProductPropertyDO> getPropertyList(ProductPropertyListReqVO listReqVO) {
|
||||
// 增加使用属性id查询
|
||||
// 增加使用属性 id 查询
|
||||
if (CollUtil.isNotEmpty(listReqVO.getPropertyIds())){
|
||||
return productPropertyMapper.selectBatchIds(listReqVO.getPropertyIds());
|
||||
}
|
||||
|
|
|
@ -87,7 +87,9 @@ public interface ProductSkuService {
|
|||
|
||||
/**
|
||||
* 基于 SPU 编号和状态,获得商品 SKU 集合
|
||||
* TODO SKU中已经不存在status属性
|
||||
*
|
||||
* TODO @puhui999:SKU中已经不存在status属性;芋艿:那就去掉 status 哈
|
||||
*
|
||||
* @param spuId SPU 编号
|
||||
* @param status 状态
|
||||
* @return 商品 SKU 集合
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package cn.iocoder.yudao.module.product.service.spu;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
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.*;
|
||||
|
@ -23,7 +20,6 @@ import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
|
|||
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 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
@ -34,7 +30,7 @@ import java.util.*;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR;
|
||||
|
||||
|
@ -63,17 +59,18 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createSpu(ProductSpuCreateReqVO createReqVO) {
|
||||
// 校验分类 TODO 暂不清楚为什么只能选择第三层的结点
|
||||
// 校验分类 TODO puhui999:暂不清楚为什么只能选择第三层的结点;芋艿:改成二级分类,因为商品只能放在叶子节点级别;
|
||||
//validateCategory(createReqVO.getCategoryId());
|
||||
// 校验品牌 TODO 暂不校验,前端没有做品牌选择
|
||||
// 校验品牌 TODO puhui999:暂不校验,前端没有做品牌选择;芋艿:可以加下哈
|
||||
//brandService.validateProductBrand(createReqVO.getBrandId());
|
||||
|
||||
List<ProductSkuCreateOrUpdateReqVO> skuSaveReqList = createReqVO.getSkus();
|
||||
// 校验SKU
|
||||
// 校验 SKU
|
||||
productSkuService.validateSkuList(skuSaveReqList, createReqVO.getSpecType());
|
||||
ProductSpuDO spu = ProductSpuConvert.INSTANCE.convert(createReqVO);
|
||||
// 初始化SPU中SKU相关属性
|
||||
// 初始化 SPU 中 SKU 相关属性
|
||||
initSpuFromSkus(spu, skuSaveReqList);
|
||||
|
||||
// 插入 SPU
|
||||
productSpuMapper.insert(spu);
|
||||
// 插入 SKU
|
||||
|
@ -193,6 +190,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
stockIncrCounts.forEach((id, incCount) -> productSpuMapper.updateStock(id, incCount));
|
||||
}
|
||||
|
||||
// TODO @puhui999:Service 尽量不做一些跟 VO 相关的拼接逻辑,目的是让 Service 更加简洁一点哈。
|
||||
@Override
|
||||
public ProductSpuDetailRespVO getSpuDetail(Long id) {
|
||||
// 获得商品 SPU
|
||||
|
@ -204,12 +202,17 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
// 查询商品 SKU
|
||||
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
|
||||
if (CollUtil.isNotEmpty(skus)){
|
||||
// TODO @puhui999:skuVOs 更简洁一点。然后大小写要注释哈。RespVOs;因为 VO 是缩写,s 是复数
|
||||
List<ProductSkuRespVO> skuRespVoS = ProductSkuConvert.INSTANCE.convertList(skus);
|
||||
// 非多规格,不需要处理
|
||||
// TODO @puhui999:统一模型,即使是单规格,也查询下,问题不大的
|
||||
if (ObjectUtil.equal(productSpuDetailRespVO.getSpecType(), true)) {
|
||||
// 获取所有的属性值id
|
||||
Set<Long> valueIds = skus.stream().flatMap(p -> p.getProperties().stream()).map(ProductSkuDO.Property::getValueId).collect(Collectors.toSet());
|
||||
// 获取所有的属性值 id
|
||||
Set<Long> valueIds = skus.stream().flatMap(p -> p.getProperties().stream())
|
||||
.map(ProductSkuDO.Property::getValueId)
|
||||
.collect(Collectors.toSet());
|
||||
List<ProductPropertyValueDetailRespBO> valueDetailList = productPropertyValueService.getPropertyValueDetailList(valueIds);
|
||||
// TODO @puhui999:拼接的逻辑,最好查询好后,丢到 convert 里面统一处理;这样 Service or Controller 也可以更简洁;原则上,Controller 去组合;Service 写逻辑;Convert 转换
|
||||
Map<Long, String> stringMap = valueDetailList.stream().collect(Collectors.toMap(ProductPropertyValueDetailRespBO::getValueId, ProductPropertyValueDetailRespBO::getValueName));
|
||||
// 设置属性值名称
|
||||
skuRespVoS.stream().flatMap(p -> p.getProperties().stream()).forEach(item ->item.setValueName(stringMap.get(item.getValueId())));
|
||||
|
@ -232,6 +235,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
|
||||
@Override
|
||||
public Map<Integer, Long> getTabsCount() {
|
||||
// TODO @puhui999:map =》counts;尽量避免出现 map 这种命名,无命名含义哈
|
||||
Map<Integer, Long> map = new HashMap<>();
|
||||
// 查询销售中的商品数量
|
||||
map.put(ProductSpuTabTypeEnum.FOR_SALE.getType(), productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.ENABLE.getStatus()));
|
||||
|
@ -240,6 +244,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||
// 查询售空的商品数量
|
||||
map.put(ProductSpuTabTypeEnum.SOLD_OUT.getType(),productSpuMapper.selectCount(ProductSpuDO::getStock, 0));
|
||||
// 查询触发警戒库存的商品数量 TODO 警戒库存暂时为 10,后期需要使用常量或者数据库配置替换
|
||||
// TODO @puhui999:要有空格;, productSpuMapper
|
||||
// TODO @puhui999:Service 不要有 Mapper 的逻辑;想想咋抽象一下哈
|
||||
map.put(ProductSpuTabTypeEnum.ALERT_STOCK.getType(),productSpuMapper.selectCount(new LambdaQueryWrapperX<ProductSpuDO>().le(ProductSpuDO::getStock, 10)));
|
||||
// 查询回收站中的商品数量
|
||||
map.put(ProductSpuTabTypeEnum.RECYCLE_BIN.getType(),productSpuMapper.selectCount(ProductSpuDO::getStatus, ProductSpuStatusEnum.RECYCLE.getStatus()));
|
||||
|
|
|
@ -5,11 +5,11 @@ import cn.hutool.core.map.MapUtil;
|
|||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
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.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.ProductSpuPageRespVO;
|
||||
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;
|
||||
|
@ -34,7 +34,6 @@ import java.util.*;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue;
|
||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
|
@ -79,13 +78,10 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
|||
@Test
|
||||
public void testCreateSpu_success() {
|
||||
// 准备参数
|
||||
ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class, o -> {
|
||||
o.setSpecType(true);
|
||||
});
|
||||
ProductSpuCreateReqVO createReqVO = randomPojo(ProductSpuCreateReqVO.class);
|
||||
Long spu = productSpuService.createSpu(createReqVO);
|
||||
ProductSpuDO productSpuDO = productSpuMapper.selectById(spu);
|
||||
assertPojoEquals(createReqVO, productSpuDO);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -96,7 +92,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
|||
// 准备参数
|
||||
ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> {
|
||||
o.setId(createReqVO.getId()); // 设置更新的 ID
|
||||
o.setSpecType(true);
|
||||
});
|
||||
// 调用
|
||||
productSpuService.updateSpu(reqVO);
|
||||
|
@ -107,9 +102,7 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
|||
|
||||
@Test
|
||||
public void testValidateSpuExists_exception() {
|
||||
ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class, o -> {
|
||||
o.setSpecType(true);
|
||||
});
|
||||
ProductSpuUpdateReqVO reqVO = randomPojo(ProductSpuUpdateReqVO.class);
|
||||
// 调用
|
||||
Assertions.assertThrows(ServiceException.class, () -> productSpuService.updateSpu(reqVO));
|
||||
}
|
||||
|
@ -174,7 +167,6 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
|||
//o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性
|
||||
//o.setMaxPrice(50);
|
||||
o.setMarketPrice(25);
|
||||
o.setSpecType(false);
|
||||
o.setBrandId(brandId);
|
||||
o.setCategoryId(categoryId);
|
||||
//o.setClickCount(100);
|
||||
|
@ -222,8 +214,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest {
|
|||
//o.setMinPrice(1); // TODO ProductSpuDO中已没有相关属性
|
||||
//o.setMaxPrice(1);
|
||||
o.setMarketPrice(1);
|
||||
o.setSpecType(false);
|
||||
o.setBrandId(brandId);
|
||||
o.setSpecType(false);
|
||||
o.setCategoryId(categoryId);
|
||||
//o.setClickCount(1); // TODO ProductSpuDO中已没有相关属性
|
||||
//o.setCode(generateNo());
|
||||
|
|
Loading…
Reference in New Issue