商品中心—4.商品属性与状态流转的技术文档

大纲

1.商品属性库系统简介

2.商品属性库系统数据库设计

3.商品属性库系统对品类添加属性

4.商品属性库系统添加属性值与属性组

5.商品属性库系统添加属性模版及模版内容

6.查询属性库系统数据相关接口

7.商品属性库系统与商品M端系统对接

8.商品状态变更流转架构设计与实现

9.商品状态变更流转的策略模式实现

10.商品状态变更流转的具体策略实现

1.商品属性库系统简介

(1)属性分类

(2)属性模版

(3)属性组

(4)属性库运行流程

(1)属性分类

为了⽅便管理商品,可以将属性分为三类:

一.基础属性

商品的通⽤属性,例如名称、品牌、品类等。

二.销售属性

商品的销售价格属性,不同销售属性的商品,其销售价会有所不同,例如⼿机的颜⾊、内存等。

三.搜索属性

商品搜索的属性,例如名称、品牌、品类等。

(2)属性模版

为了提⾼效率,合理化运营,会将商品的属性与品类绑定到⼀起。品类是以树形结构来管理的。既然属性与品类绑定在⼀起,为避免重复添加属性,会将每级品类的公共属性抽取出来作为⼀个属性模板。后期关联商品查询时,可以将属性最终展示在商品下⾯。

(3)属性组

由于商品的属性很多,为了⽅便⽤户浏览和数据⽐对,需要对属性进⾏分组管理。

一.电子产品属性组

二.汽车属性组

(4)属性库运行流程

一.创建属性库数据

二.查询属性库数据

三.商品对接属性库

2.商品属性库系统数据库设计

(1)属性相关表的关系

(2)属性相关表的详情

(1)属性相关表的关系

属性表管理:attribute management,简称atm。

一个品类会关联一个属性模版,一个属性模版里会有多个属性组或多个属性,一个属性组里会有多个属性,一个属性里会有多个属性值。

(2)属性相关表的详情

一.属性表

二.属性可选值表

三.属性组表

四.属性模板表

五.属性模板内容表

六.标品商品属性值表

一.属性表

create table if not exists atm_attribute_info ( 
    id int(10) auto_increment comment '主键' primary key,
    category_id int(10) default null comment '品类id',
    attribute_name varchar(128) not null comment '属性名称',
    attribute_code varchar(128) null comment '属性编码',
    attribute_type varchar(128) not null comment '属性类型,格式为json数组(1-基础属性,2-销售属性,3-搜索属性,null-其他属性)',
    attribute_input_type int not null comment '属性值的输⼊⽅式(1-⽤户⾃⼰输⼊,2-单选下拉框,3-多选下拉框,4-⽇期)',
    attribute_comment varchar(128) default null comment '属性说明',
    del_flag tinyint(1) default 0 not null comment '删除标记(1-有效,0-删除)',
    create_user int not null comment '创建⼈',
    create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_user int not null comment '更新⼈',
    update_time datetime default CURRENT_TIMESTAMP not null comment '修改时间'
) comment '属性表';

例如添加三个属性:品牌、颜色、版本。

二.属性可选值表

create table if not exists atm_attribute_value (
    id int(10) auto_increment comment '主键' primary key,
    attribute_id int(10) not null comment '属性id',
    attribute_value varchar(128) not null comment '属性值',
    sort int not null comment '排序序号',
    del_flag tinyint(1) default 0 not null comment '删除标记(1-有效,0-删除)',
    create_user int not null comment '创建⼈',
    create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_user int not null comment '更新⼈',
    update_time datetime default CURRENT_TIMESTAMP not null comment '修改时间'
) comment '属性值表';

例如给颜色属性添加了3个可选值:红色、黄色、蓝色。例如给版本属性添加了3个可选值:公开版、无线耳机套装、智能手表套装。

三.属性组表

create table if not exists atm_attribute_group (
    id int(10) auto_increment comment '主键' primary key,
    category_id int(10) default null comment '品类id',
    group_name varchar(128) not null comment '属性组名称',
    del_flag tinyint(1) default 0 not null comment '删除标记(1-有效,0-删除)',
    create_user int not null comment '创建⼈',
    create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_user int not null comment '更新⼈',
    update_time datetime default CURRENT_TIMESTAMP not null comment '修改时间'
) comment '属性组表';

例如添加一个属性组:基本属性组。

四.属性模板表

create table atm_attribute_template (
    id int auto_increment comment '主键' primary key,
    template_name varchar(128) not null comment '属性模板名称',
    category_id int not null comment '品类id',
    del_flag tinyint(1) default 0 not null comment '删除标记(1-有效,0-删除)',
    create_user int not null comment '创建⼈',
    create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_user int not null comment '更新⼈',
    update_time datetime default CURRENT_TIMESTAMP not null comment '修改时间'
) comment '属性模板表';

例如添加一个属性模版:智能手机模版;

五.属性模板内容表

create table atm_attribute_template_content (
    id int auto_increment comment '主键' primary key,
    template_id int not null comment '属性模板id',
    group_id int null comment '属性组id',
    attribute_id int not null comment '属性id',
    participant_type int not null comment '参与类型(1-表示该属性是放到item上的,2-表示该属性是放到sku上的)',
    sort int null comment '排序序号',
    del_flag tinyint(1) default 0 not null comment '删除标记(1-有效,0-删除)',
    create_user int not null comment '创建⼈',
    create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_user int not null comment '更新⼈',
    update_time datetime default CURRENT_TIMESTAMP not null comment '修改时间'
) comment '模板内容表';

例如给智能⼿机模板配置三个属性,同时指定每个属性所属的属性组,分别为品牌属性(⽆属性组)、颜⾊属性和版本属性(属于基本属性组)。另外配置品牌属性放到item上,颜⾊和版本属性放到sku上,而且属性组的顺序分别是品牌、颜⾊、版本。

六.标品商品属性值表

create table atm_item_sku_attribute_value (
    id int auto_increment comment '主键' primary key,
    participant_id varchar(64) not null comment '标品id或商品id',
    participant_type int not null comment '参与类型(1-表示该属性是放到item上的,2-表示该属性是放到sku上的)',
    template_id int not null comment '模板id',
    group_id int null comment '属性组id',
    attribute_id int not null comment '属性id',
    attribute_value varchar(128) not null comment '属性值',
    sort int not null comment '排序序号',
    del_flag tinyint(1) default 0 not null comment '删除标记(1-有效,0-删除)',
    create_user int not null comment '创建⼈',
    create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_user int not null comment '更新⼈',
    update_time datetime default CURRENT_TIMESTAMP not null comment '修改时间'
) comment '标品商品属性值表';

例如item为111的标品,关联了品牌属性,值为华为。sku为222的商品关联了颜⾊属性(红色),版本属性(公开版)。sku为333的商品关联了颜⾊属性(黄色),版本属性(⽆线⽿机套装)。sku为444的商品关联了颜⾊属性(蓝色),版本属性(智能⼿表套装)。

3.商品属性库系统对品类添加属性

//属性管理相关操作API
@DubboService(version = "1.0.0", interfaceClass = AttributeApi.class, retries = 0)
public class AttributeApiImpl implements AttributeApi {
    @Autowired
    private AttributeService attributeService;
    
    //添加属性接口
    @Override
    public JsonResult<AttributeInfoResultDTO> saveAttribute(AttributeInfoRequest request) {
        AttributeInfoResultDTO attributeResultV2DTO = attributeService.saveAttributeInfo(request);
        return JsonResult.buildSuccess(attributeResultV2DTO);
    }
    ...
}

//新增/编辑属性请求入参
@Data
public class AttributeInfoRequest implements Serializable {
    //品类id
    private Long categoryId;
    //属性名称
    private String attributeName;
    //属性编码
    private String attributeCode;
    //属性类型
    private String attributeType;
    //属性值的输入方式
    private Integer attributeInputType;
    //属性说明
    private String attributeComment;
    //操作人
    @NotNull(message = "操作人[operateUser]不能为空")
    private Integer operateUser;
}

//属性管理相关操作API
@Service
public class AttributeServiceImpl implements AttributeService {
    @Autowired
    private AttributeRepository attributeRepository;
    
    //添加属性
    @Override
    public AttributeInfoResultDTO saveAttributeInfo(AttributeInfoRequest request) {
        //入参检查
        checkAttributeInfoRequest(request);
        //保存属性
        Long attributeId = attributeRepository.saveAttributeInfo(request);
        return new AttributeInfoResultDTO(attributeId, true);
    }
    ...
}

@Repository
public class AttributeRepository {
    @Resource
    private AttributeInfoMapper attributeInfoMapper;
    ...
    
    //保存属性信息
    public Long saveAttributeInfo(AttributeInfoRequest request) {
        AttributeInfoDO attributeInfoDO = attributeConverter.convertAttributeInfoDO(request);
        attributeInfoDO.initCommon();
        attributeInfoMapper.insert(attributeInfoDO);
        return attributeInfoDO.getId();
    }
    ...
}

4.商品属性库系统添加属性值与属性组

(1)添加可选的属性值

(2)添加属性组

(1)添加可选的属性值

//属性管理相关操作API
@DubboService(version = "1.0.0", interfaceClass = AttributeApi.class, retries = 0)
public class AttributeApiImpl implements AttributeApi {
    ...
    @Autowired
    private AttributeService attributeService;
    
    //给属性添加可选的属性值接口
    @Override
    public JsonResult<AttributeValueResultDTO> saveAttributeValue(List<AttributeValueRequest> list) {
        AttributeValueResultDTO attributeValueResultDTO = attributeService.saveAttributeValues(list);
        return JsonResult.buildSuccess(attributeValueResultDTO);
    }
    ...
}

//属性管理相关操作API
@Service
public class AttributeServiceImpl implements AttributeService {
    @Autowired
    private AttributeRepository attributeRepository;
    ...
    
    //批量给属性添加可选的属性值
    @Override
    public AttributeValueResultDTO saveAttributeValues(List<AttributeValueRequest> list) {
        attributeRepository.saveAttributeValues(list);
        return new AttributeValueResultDTO(true);
    }
    ...
}

//属性库
@Repository
public class AttributeRepository {
    @Resource
    private AttributeValueMapper attributeValueV2Mapper;
    ...
    
    //批量保存属性值
    public void saveAttributeValues(List<AttributeValueRequest> list) {
        //先删
        LambdaQueryWrapper<AttributeValueDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AttributeValueDO::getAttributeId, list.get(0).getAttributeId());
        attributeValueV2Mapper.delete(queryWrapper);
        //后保存
        List<AttributeValueDO> attributeValueDOS = attributeConverter.convertAttributeValueV2DOList(list);
        attributeValueDOS.forEach(e -> {
            e.setUpdateUser(list.get(0).getOperateUser());
            e.initCommon();
        });
        Integer count = attributeValueV2Mapper.insertBatch(attributeValueDOS);
        if (count <= 0) {
            throw new ProductBizException(CommonErrorCodeEnum.SQL_ERROR);
        }
    }
    ...
}

(2)添加属性组

//属性管理相关操作API
@DubboService(version = "1.0.0", interfaceClass = AttributeApi.class, retries = 0)
public class AttributeApiImpl implements AttributeApi {
    ...
    @Autowired
    private AttributeService attributeService;
    
    //添加属性组接口
    @Override
    public JsonResult<AttributeGroupResultDTO> saveAttributeGroup(AttributeGroupRequest request) {
        AttributeGroupResultDTO attributeGroupResultDTO = attributeService.saveAttributeGroup(request);
        return JsonResult.buildSuccess(attributeGroupResultDTO);
    }
    ...
}

//属性管理相关操作API
@Service
public class AttributeServiceImpl implements AttributeService {
    @Autowired
    private AttributeRepository attributeRepository;
    ...
    
    //添加属性组接口
    @Override
    public AttributeGroupResultDTO saveAttributeGroup(AttributeGroupRequest request) {
        //入参检查
        checkAttributeGroupRequest(request);
        Long groupId = attributeRepository.saveAttributeGroup(request);
        return new AttributeGroupResultDTO(groupId, true);
    }
    ...
}

//属性库
@Repository
public class AttributeRepository {
    @Resource
    private AttributeGroupMapper attributeGroupMapper;
    ...
    
    //保存属性组
    public Long saveAttributeGroup(AttributeGroupRequest request) {
        AttributeGroupDO attributeGroupDO = attributeConverter.convertAttributeGroupDO(request);
        attributeGroupDO.initCommon();
        attributeGroupMapper.insert(attributeGroupDO);
        return attributeGroupDO.getId();
    }
    ...
}

5.商品属性库系统添加属性模版及模版内容

一个品类会关联一个属性模版,一个属性模版里会有多个属性组或多个属性,一个属性组里会有多个属性,一个属性里会有多个属性值。

//属性管理相关操作API
@DubboService(version = "1.0.0", interfaceClass = AttributeApi.class, retries = 0)
public class AttributeApiImpl implements AttributeApi {
    ...
    @Autowired
    private AttributeService attributeService;
    
    //添加属性模板接口
    @Override
    public JsonResult<AttributeTemplateResultDTO> saveAttributeTemplate(AttributeTemplateRequest request) {
        AttributeTemplateResultDTO attributeTemplateResultDTO = attributeService.saveAttributeTemplate(request);
        return JsonResult.buildSuccess(attributeTemplateResultDTO);
    }
    
    //给模板添加模板内容接口
    @Override
    public JsonResult<AttributeTemplateContentResultDTO> saveAttributeTemplateContents(List<AttributeTemplateContentRequest> list) {
        AttributeTemplateContentResultDTO attributeTemplateContentResultDTO = attributeService.saveAttributeTemplateContents(list);
        return JsonResult.buildSuccess(attributeTemplateContentResultDTO);
    }
    ...
}

//属性管理相关操作API
@Service
public class AttributeServiceImpl implements AttributeService {
    @Autowired
    private AttributeRepository attributeRepository;
    ...
    
    //添加属性模板接口
    @Override
    public AttributeTemplateResultDTO saveAttributeTemplate(AttributeTemplateRequest request) {
        //入参检查
        checkAttributeTemplateRequest(request);
        Long templteId = attributeRepository.saveAttributeTemplate(request);
        return new AttributeTemplateResultDTO(templteId, true);
    }
    
    //添加属性模板内容接口
    @Override
    public AttributeTemplateContentResultDTO saveAttributeTemplateContents(List<AttributeTemplateContentRequest> list) {
        //入参检查
        checkAttributeTemplateContentRequest(list);
        attributeRepository.saveAttributeTemplateContents(list);
        return new AttributeTemplateContentResultDTO(true);
    }
    ...
}

//属性库
@Repository
public class AttributeRepository {
    @Resource
    private AttributeTemplateMapper attributeTemplateMapper;
    
    @Resource
    private AttributeTemplateContentMapper attributeTemplateContentMapper;
    ...
    
    //保存属性模板
    public Long saveAttributeTemplate(AttributeTemplateRequest request) {
        AttributeTemplateDO attributeTemplateDO = attributeConverter.convertAttributeTemplateDO(request);
        attributeTemplateDO.initCommon();
        attributeTemplateMapper.insert(attributeTemplateDO);
        return attributeTemplateDO.getId();
    }
    
    //保存属性模板内容
    public void saveAttributeTemplateContents(List<AttributeTemplateContentRequest> list) {
        //先删
        LambdaQueryWrapper<AttributeTemplateContentDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AttributeTemplateContentDO::getTemplateId, list.get(0).getTemplateId());
        attributeTemplateContentMapper.delete(queryWrapper);
        //后保存
        List<AttributeTemplateContentDO> attributeTemplateContentDOS = attributeConverter.convertAttributeTemplateContentDOList(list);
        attributeTemplateContentDOS.forEach(e -> {
            e.setUpdateUser(list.get(0).getOperateUser());
            e.initCommon();
        });
        Integer count = attributeTemplateContentMapper.insertBatch(attributeTemplateContentDOS);
        if (count <= 0) {
            throw new ProductBizException(CommonErrorCodeEnum.SQL_ERROR);
        }
    }
    ...
}

6.查询属性库系统数据相关接口

//属性管理相关操作API
@DubboService(version = "1.0.0", interfaceClass = AttributeApi.class, retries = 0)
public class AttributeApiImpl implements AttributeApi {
    ...
    @Autowired
    private AttributeService attributeService;
    
    //属性分页查询接口
    @Override
    public JsonResult<PageResult<AttributeInfoDTO>> pageAttributeInfo(QueryAttributeInfoRequest request) {
        PageResult<AttributeInfoDTO> pageResult = attributeService.pageAttributeInfo(request);
        return JsonResult.buildSuccess(pageResult);
    }
    
    //根据属性id查询属性及可选的属性值
    @Override
    public JsonResult<List<AttributeValueDTO>> queryAttributeValueByAttributeId(Long attributeId) {
        List<AttributeValueDTO> attributeValueDTOS = attributeService.queryAttributeValueByAttributeId(attributeId);
        return JsonResult.buildSuccess(attributeValueDTOS);
    }
    
    //属性组分页查询接口
    @Override
    public JsonResult<PageResult<AttributeGroupDTO>> pageAttributeGroup(QueryAttributeGroupRequest request) {
        PageResult<AttributeGroupDTO> pageResult = attributeService.pageAttributeGroup(request);
        return JsonResult.buildSuccess(pageResult);
    }
    
    //属性模板分页查询接口
    @Override
    public JsonResult<PageResult<AttributeTemplateDTO>> pageAttributeTemplate(QueryAttributeTemplateRequest request) {
        PageResult<AttributeTemplateDTO> pageResult = attributeService.pageAttributeTemplate(request);
        return JsonResult.buildSuccess(pageResult);
    }
    
    //根据模板id查询模板内容接口
    @Override
    public JsonResult<List<AttributeTemplateContentDTO>> queryAttributeTemplateContentByTemplateId(Long templateId) {
        List<AttributeTemplateContentDTO> attributeTemplateContentDTOS = attributeService.queryAttributeTemplateContentByTemplateId(templateId);
        return JsonResult.buildSuccess(attributeTemplateContentDTOS);
    }
    ...
}

//属性管理相关操作API
@Service
public class AttributeServiceImpl implements AttributeService {
    @Autowired
    private AttributeRepository attributeRepository;
    
    //分页查询属性
    @Override
    public PageResult<AttributeInfoDTO> pageAttributeInfo(QueryAttributeInfoRequest request) {
        return attributeRepository.pageAttributeInfo(request);
    }
    
    //根据属性id查询属性及可选的属性值
    @Override
    public List<AttributeValueDTO> queryAttributeValueByAttributeId(Long attributeId) {
        if (attributeId == null || attributeId < 0) {
            return null;
        }
        return attributeRepository.queryAttributeValueByAttributeId(attributeId);
    }
    
    //分页查询属性组
    @Override
    public PageResult<AttributeGroupDTO> pageAttributeGroup(QueryAttributeGroupRequest request) {
        return attributeRepository.pageAttributeGroup(request);
    }
    
    //分页查询属性模板
    @Override
    public PageResult<AttributeTemplateDTO> pageAttributeTemplate(QueryAttributeTemplateRequest request) {
        return attributeRepository.pageAttributeTemplate(request);
    }
    
    //根据属性模板id查询属性模板的内容
    @Override
    public List<AttributeTemplateContentDTO> queryAttributeTemplateContentByTemplateId(Long templateId) {
        if (templateId == null || templateId < 0) {
            return null;
        }
        return attributeRepository.queryAttributeTemplateContentByTemplateId(templateId);
    }
    ...
}

//属性库
@Repository
public class AttributeRepository {
    @Resource
    private AttributeGroupMapper attributeGroupMapper;
    
    //分页查询属性
    public PageResult<AttributeInfoDTO> pageAttributeInfo(QueryAttributeInfoRequest request) {
        LambdaQueryWrapper<AttributeInfoDO> queryWrapper = Wrappers.lambdaQuery();
        if (request.getCategoryId() != null && request.getCategoryId() > 0) {
            queryWrapper.eq(AttributeInfoDO::getCategoryId, request.getCategoryId());
        }
        if (StringUtils.isNotBlank(request.getAttributeName())) {
            queryWrapper.like(AttributeInfoDO::getAttributeName, request.getAttributeName());
        }
        if (StringUtils.isNotBlank(request.getAttributeCode())) {
            queryWrapper.like(AttributeInfoDO::getAttributeCode, request.getAttributeCode());
        }
        if (request.getAttributeType() != null) {
            queryWrapper.eq(AttributeInfoDO::getAttributeType, request.getAttributeType());
        }
        if (request.getAttributeInputType() != null) {
            queryWrapper.eq(AttributeInfoDO::getAttributeInputType, request.getAttributeInputType());
        }
        Page<AttributeInfoDO> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<AttributeInfoDO> pageResult = attributeInfoMapper.selectPage(page, queryWrapper);
        return attributeConverter.convertAttributeInfoDTOPageResult(pageResult);
    }
    
    //根据属性id查询属性值
    public List<AttributeValueDTO> queryAttributeValueByAttributeId(Long attributeId) {
        LambdaQueryWrapper<AttributeValueDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AttributeValueDO::getAttributeId, attributeId);
        List<AttributeValueDO> attributeValueDOS = attributeValueV2Mapper.selectList(queryWrapper);
        return attributeConverter.convertAttributeValueV2DTOList(attributeValueDOS);
    }
    
    //分页查询属性组
    public PageResult<AttributeGroupDTO> pageAttributeGroup(QueryAttributeGroupRequest request) {
        LambdaQueryWrapper<AttributeGroupDO> queryWrapper = Wrappers.lambdaQuery();
        if (request.getCategoryId() != null && request.getCategoryId() > 0) {
            queryWrapper.eq(AttributeGroupDO::getCategoryId, request.getCategoryId());
        }
        if (StringUtils.isNotBlank(request.getGroupName())) {
            queryWrapper.like(AttributeGroupDO::getGroupName, request.getGroupName());
        }
        Page<AttributeGroupDO> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<AttributeGroupDO> pageResult = attributeGroupMapper.selectPage(page, queryWrapper);
        return attributeConverter.convertAttributeGroupDTOPageResult(pageResult);
    }
    
    //分页查询属性模板
    public PageResult<AttributeTemplateDTO> pageAttributeTemplate(QueryAttributeTemplateRequest request) {
        LambdaQueryWrapper<AttributeTemplateDO> queryWrapper = Wrappers.lambdaQuery();
        if (request.getCategoryId() != null && request.getCategoryId() > 0) {
            queryWrapper.eq(AttributeTemplateDO::getCategoryId, request.getCategoryId());
        }
        if (StringUtils.isNotBlank(request.getTemplateName())) {
            queryWrapper.like(AttributeTemplateDO::getTemplateName, request.getTemplateName());
        }
        Page<AttributeTemplateDO> page = new Page<>(request.getPageNum(), request.getPageSize());
        Page<AttributeTemplateDO> pageResult = attributeTemplateMapper.selectPage(page, queryWrapper);
        return attributeConverter.convertAttributeTemplateDTOPageResult(pageResult);
    }
    
    //根据属性模板id查询属性模板内容
    public List<AttributeTemplateContentDTO> queryAttributeTemplateContentByTemplateId(Long templateId) {
        LambdaQueryWrapper<AttributeTemplateContentDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AttributeTemplateContentDO::getTemplateId, templateId);
        List<AttributeTemplateContentDO> attributeTemplateContentDOS = attributeTemplateContentMapper.selectList(queryWrapper);
        return attributeConverter.convertAttributeTemplateContentDTOList(attributeTemplateContentDOS);
    }    
    ...
}

7.商品属性库系统与商品M端系统对接

//商品属性相关操作API
@DubboService(version = "1.0.0", interfaceClass = ItemSkuAttributeApi.class, retries = 0)
public class ItemSkuAttributeApiImpl implements ItemSkuAttributeApi {
    @Autowired
    private ItemSkuAttributeService itemSkuAttributeService;
    
    //保存标品和商品属性接口
    @Override
    public JsonResult<ItemSkuAttributeValueResultDTO> saveItemSkuAttributeValue(List<ItemSkuAttributeValueRequest> list) {
        ItemSkuAttributeValueResultDTO itemSkuAttributeValueResultDTO = itemSkuAttributeService.saveItemSkuAttributeValue(list);
        return JsonResult.buildSuccess(itemSkuAttributeValueResultDTO);
    }
    
    //根据商品id品类id查询聚合商品属性值接口
    @Override
    public JsonResult<List<SkuAttributeValueDTO>> queryItemSkuAttributeValueList(QueryItemSkuAttributeValueRequest request) {
        List<SkuAttributeValueDTO> skuAttributeValueDTOS = itemSkuAttributeService.queryItemSkuAttributeValueList(request);
        return JsonResult.buildSuccess(skuAttributeValueDTOS);
    }
    
    //根据属性查询条件搜索商品接口
    @Override
    public JsonResult<List<String>> querySkuIdsByAttribute(QuerySkuIdsByAttributeRequest request) {
        List<String> skuIds = itemSkuAttributeService.querySkuIdsByAttributes(request);
        return JsonResult.buildSuccess(skuIds);
    }
}

//商品属性相关操作API
@Service
public class ItemSkuAttributeServiceImpl implements ItemSkuAttributeService {
    @Autowired
    private AttributeRepository attributeRepository;
    
    //保存标品和商品属性
    @Override
    public ItemSkuAttributeValueResultDTO saveItemSkuAttributeValue(List<ItemSkuAttributeValueRequest> list) {
        //入参检查
        checkItemSkuAttributeValueRequest(list);
        attributeRepository.saveItemSkuAttributeValue(list);
        return new ItemSkuAttributeValueResultDTO(true);
    }
    
    //根据商品id类目id查询聚合商品属性值接口
    @Override
    public List<SkuAttributeValueDTO> queryItemSkuAttributeValueList(QueryItemSkuAttributeValueRequest request) {
        //1.根据skuId和itemId查询出商品所有的属性
        List<ItemSkuAttributeValueDTO> itemSkuAttributeValueDTOS = attributeRepository.queryItemSkuAttributeValueList(request);
        //2.找出使用这个sku使用的是哪个模板
        Long templateId = itemSkuAttributeValueDTOS.get(0).getTemplateId();
        //3.查询出模板内容
        List<AttributeTemplateContentDTO> attributeTemplateContentDTOS = attributeRepository.queryAttributeTemplateContentByTemplateId(templateId);
        //4.查询出相关的属性组
        List<Long> groupIds = attributeTemplateContentDTOS.stream()
            .map(AttributeTemplateContentDTO::getGroupId)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
        List<AttributeGroupDTO> groupDTOS = attributeRepository.queryGroups(groupIds);
        Map<Long, String> groupIdAndNameMap = groupDTOS.stream().collect(Collectors.toMap(AttributeGroupDTO::getId, AttributeGroupDTO::getGroupName));
        //5.查询出相关的属性
        List<Long> attributeIds = attributeTemplateContentDTOS.stream()
            .map(AttributeTemplateContentDTO::getAttributeId)
            .collect(Collectors.toList());
        List<AttributeInfoDTO> attributeInfoDTOS = attributeRepository.queryAttributeInfos(attributeIds);
        Map<Long, String> attributeIdAndNameMap = attributeInfoDTOS.stream().collect(Collectors.toMap(AttributeInfoDTO::getId, AttributeInfoDTO::getAttributeName));
        //6.拼装结果
        return buildSkuAttributeValueDTOS(itemSkuAttributeValueDTOS, groupIdAndNameMap, attributeIdAndNameMap);
    }
    
    //根据属性查询条件搜索商品接口
    @Override
    public List<String> querySkuIdsByAttributes(QuerySkuIdsByAttributeRequest request) {
        return attributeRepository.querySkuIdsByAttribute(request);
    }
    ...
}

//属性库
@Repository
public class AttributeRepository {
    ...
    //保存标品和商品属性
    public void saveItemSkuAttributeValue(List<ItemSkuAttributeValueRequest> list) {
        //先删
        LambdaQueryWrapper<ItemSkuAttributeValueDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ItemSkuAttributeValueDO::getParticipantId, list.get(0).getParticipantId());
        itemSkuAttributeValueMapper.delete(queryWrapper);
        //后保存
        List<ItemSkuAttributeValueDO> itemSkuAttributeValueDOS = attributeConverter.convertItemSkuAttributeValueDOList(list);
        itemSkuAttributeValueDOS.forEach(e -> {
            e.setUpdateUser(list.get(0).getOperateUser());
            e.initCommon();
        });
        Integer count = itemSkuAttributeValueMapper.insertBatch(itemSkuAttributeValueDOS);
        if (count <= 0) {
            throw new ProductBizException(CommonErrorCodeEnum.SQL_ERROR);
        }
    }
    
    //根据商品id类目id查询聚合商品属性值接口
    public List<ItemSkuAttributeValueDTO> queryItemSkuAttributeValueList(QueryItemSkuAttributeValueRequest request) {
        LambdaQueryWrapper<ItemSkuAttributeValueDO> queryWrapper = Wrappers.lambdaQuery();
        List<String> participantIds = new ArrayList<>();
        if (StringUtils.isNotBlank(request.getItemId())) {
            participantIds.add(request.getItemId());
        }
        if (StringUtils.isNotBlank(request.getSkuId())) {
            participantIds.add(request.getSkuId());
        }
        queryWrapper.in(ItemSkuAttributeValueDO::getParticipantId, participantIds.stream().distinct().collect(Collectors.toList()));
        List<ItemSkuAttributeValueDO> itemSkuAttributeValueDOS = itemSkuAttributeValueMapper.selectList(queryWrapper);
        return attributeConverter.convertItemSkuAttributeValueDTO(itemSkuAttributeValueDOS);
    }
    
    //根据属性模板id查询属性模板内容
    public List<AttributeTemplateContentDTO> queryAttributeTemplateContentByTemplateId(Long templateId) {
        LambdaQueryWrapper<AttributeTemplateContentDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(AttributeTemplateContentDO::getTemplateId, templateId);
        List<AttributeTemplateContentDO> attributeTemplateContentDOS = attributeTemplateContentMapper
            .selectList(queryWrapper);
        return attributeConverter.convertAttributeTemplateContentDTOList(attributeTemplateContentDOS);
    }
    
    //根据id批量查询属性组
    public List<AttributeGroupDTO> queryGroups(List<Long> groupIds) {
        List<AttributeGroupDO> attributeGroupDOS = attributeGroupMapper.selectBatchIds(groupIds);
        return attributeConverter.convertAttributeGroupDTOList(attributeGroupDOS);
    }
    
    //根据id批量查询属性
    public List<AttributeInfoDTO> queryAttributeInfos(List<Long> attributeIds) {
        List<AttributeInfoDO> attributeInfoDOS = attributeInfoMapper.selectBatchIds(attributeIds);
        return attributeConverter.convertAttributeInfoDTOList(attributeInfoDOS);
    }
    
    //根据属性查询条件搜索商品接口
    public List<String> querySkuIdsByAttribute(QuerySkuIdsByAttributeRequest request) {
        LambdaQueryWrapper<ItemSkuAttributeValueDO> queryWrapper = Wrappers.lambdaQuery();
        for (QuerySkuIdsByAttributeRequest.AttributeCriteria attributeCriteria : request.getAttributeCriterias()) {
            queryWrapper.or(wrapper -> wrapper
                .eq(ItemSkuAttributeValueDO::getAttributeId, attributeCriteria.getAttributeId())
                .like(ItemSkuAttributeValueDO::getAttributeValue, attributeCriteria.getAttributeValue())
            );
        }
        List<ItemSkuAttributeValueDO> itemSkuAttributeValueDOS = itemSkuAttributeValueMapper.selectList(queryWrapper);
        return itemSkuAttributeValueDOS.stream().map(ItemSkuAttributeValueDO::getParticipantId).collect(Collectors.toList());
    }
    ...
}

8.商品状态变更流转架构设计

(1)状态流转策略表

(2)商品状态变更流向图

(3)接口实现流程图

(1)状态流转策略表

CREATE TABLE `product_status_strategy` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
    `start_status` int(10)  NOT NULL DEFAULT '0' COMMENT '起始状态',
    `end_status` int(10)  NOT NULL DEFAULT '0' COMMENT '截⽌状态',
    `strategy_code` varchar(64) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '策略映射码',
    `business_code` varchar(64) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '业务编码',
    `version_id` int(10) NOT NULL DEFAULT '0' COMMENT '版本号',
    `del_flag` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记(1-有效,0-删除)',
    `create_user` int(10) NOT NULL DEFAULT '0' COMMENT '创建⼈',
    `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
    `update_user` int(10) NOT NULL DEFAULT '0' COMMENT '更新⼈',
    `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='状态流转策略表';

(2)商品状态变更流向图

说明:严格按照箭头方向执行,除了可重新上架,其他状态变更均不可逆。

(3)接口实现流程图

9.商品状态变更流转的策略模式实现

具体实现在商品M端系统:

一.验证⼊参必填(商品ID和变更状态)

二.验证商品是否存在,停售状态禁⽌变更状态

三.获取状态流转策略表,根据商品的当前状态和变更状态获取配置的映射策略类的实例名称

四.实现关于每个状态变更的具体逻辑

//商品状态变更请求入参
@Data
public class ProductStatusRequest implements Serializable {
    //商品ID
    private String itemId;
    
    //商品变更状态(1-准备上架、2-试销上架、3-上架、4-预下架、5-下架、6-停售)
    private Integer itemStatus;
}

@Service
public class ProductServiceImpl implements ProductService {
    ...
    //修改商品状态
    @Override
    public void updateProductStatus(ProductStatusRequest productStatusRequest) {
        //1.验证入参
        checkUpdateProductStatusParam(productStatusRequest);
        //2.获取商品对应的信息
        ItemInfoDO itemInfoDO = productInfoRepository.getItemByItemId(productStatusRequest.getItemId());
        //停售状态不允许操作
        if (itemInfoDO.getItemStatus().equals(ProductStatusEnum.STOP_SALE.getCode())) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_STATUS_ERROR);
        }
        //3.获取商品状态变更配置策略
        String productStatusStrategy = productInfoRepository.getProductStatusStrategy(itemInfoDO.getItemStatus(), productStatusRequest.getItemStatus(), ProductConstants.PRODUCT_UPDATE_STATUS);
        //4.策略调用具体变更实现类
        updateProductStatus(productStatusRequest, productStatusStrategy);
    }
    
    //通过策略模式更新商品状态
    private void updateProductStatus(ProductStatusRequest productStatusRequest, String productStatusStrategy) {
        AbstractStatusStrategy strategy = productStatusStrategyFactory.getStrategy(productStatusStrategy);
        if (null == strategy) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_STRATEGY_ERROR);
        }
        //通过策略模式,调用底层对应的状态变更方法
        strategy.updateProductStatus(productStatusRequest);
    }
    ...
}

@Repository
public class ProductInfoRepository {
    ...
    //根据itemId查询item信息
    public ItemInfoDO getItemByItemId(String itemId) {
        ItemInfoDO itemInfoDO = itemInfoMapper.selectByItemId(itemId);
        if (Objects.isNull(itemInfoDO)) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_DETAIL_NULL);
        }
        return itemInfoDO;
    }
    
    //获取对应的修改状态流程策略映射码
    public String getProductStatusStrategy(Integer startStatus, Integer endStatus, String businessCode) {
        LambdaQueryWrapper<ProductStatusStrategyDO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ProductStatusStrategyDO::getStartStatus, startStatus);
        queryWrapper.eq(ProductStatusStrategyDO::getEndStatus, endStatus);
        queryWrapper.eq(ProductStatusStrategyDO::getBusinessCode, businessCode);
        ProductStatusStrategyDO productStatusStrategy = productStatusStrategyMapper.selectOne(queryWrapper);
        if (Objects.isNull(productStatusStrategy)) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_STRATEGY_NULL);
        }
        return productStatusStrategy.getStrategyCode();
    }
    ...
}

//商品状态变更策略工厂
@Component
public class ProductStatusStrategyFactory {
    //@Autowired会把所有继承了AbstractStatusStrategy抽象类的Bean实例,加载到productStatusMap中
    @Autowired
    private Map<String, AbstractStatusStrategy> productStatusMap = new ConcurrentHashMap<>(16);
    
    //获取 商品状态变更 策略实例
    public AbstractStatusStrategy getStrategy(String productStatusStrategy) {
        return productStatusMap.get(productStatusStrategy);
    }
}

//商品状态变更抽象策略
public abstract class AbstractStatusStrategy {
    //商品状态流转
    public abstract void updateProductStatus(ProductStatusRequest productStatusRequest);
}

10.商品状态变更流转的具体策略实现

(1)商品试销上架的实现

(2)商品上架与预下架状态流转实现

(3)商品下架和停售状态流转实现

(4)流转到上架的状态变更

(1)商品试销上架的实现

一.商品试销上架时对前端销售数据校验

//试销上架状态变更
@Service("trialSaleStatus")
public class TrialSaleStatusService extends AbstractStatusStrategy {
    @Autowired
    private ProductConverter productConverter;
    
    @Autowired
    private ProductStatusRepository productStatusRepository;
    
    @Value("${trial.date-num}")
    private Integer dateNum;

    //准备上架状态 流转到试销上架
    @Transactional(rollbackFor = BaseBizException.class)
    @Override
    public void updateProductStatus(ProductStatusRequest productStatusRequest) {
        //1.验证商品和前台类目绑定关系,绑定关系有效
        checkFrontCategoryList(productStatusRequest.getItemId());
        //2.验证商品数据是否完整
        ProductDetailDO productDetailDO = checkProductInfo(productStatusRequest.getItemId());
        //3.填入补充试销商品的扩展字段(试销期截止时间)
        buildAttributeContent(productDetailDO);
        //4.变更商品信息
        updateProduct(productDetailDO, productStatusRequest);
        //5.发送商品消息变更通知对象(已做MySQL + Canal监听)
    }
    
    //检查商品是否和前台类目存在绑定关系
    private void checkFrontCategoryList(String itemId) {
        //获取类目绑定关系
        List<FrontCategoryRelationDO> frontCategoryRelationList = productStatusRepository.queryFrontCategoryList(itemId);
        //过滤状态,只保留有效的
        List<FrontCategoryRelationDO> categoryRelationDOList = frontCategoryRelationList.stream().filter(frontCategoryRelationDO -> {
            if (frontCategoryRelationDO.getDelFlag().equals(DelFlagEnum.EFFECTIVE.getCode())) {
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        //商品不存在有效的绑定关系,提示错误
        if (CollectionUtils.isEmpty(categoryRelationDOList)) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_CATEGORY_RELATION_NULL);
        }
    }
    
    //检查商品的数据完整性
    private ProductDetailDO checkProductInfo(String itemId) {
        //查询商品的详情信息
        ProductDetailDO productDetailDO = productStatusRepository.queryProductDetail(itemId);
        //验证商品完整性
        productStatusRepository.checkProductComplete(productDetailDO);
        return productDetailDO;
    }
    ...
}

@Repository
public class ProductStatusRepository {
    ...
    //查询商品的详情信息
    public ProductDetailDO queryProductDetail(String itemId) {
        List<ProductDetailDO> productDetailDOList = itemInfoMapper.queryProductInfoList(itemId);
        if (CollectionUtils.isEmpty(productDetailDOList)) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_DETAIL_NULL);
        }
        return productDetailDOList.get(0);
    }
    
    //检查商品得完整性
    public void checkProductComplete(ProductDetailDO productDetailDO) {
        //1.验证商品的存储信息是否完整 
        if (Objects.isNull(productDetailDO.getStoreConditionType()) || Objects.isNull(StoreLabelEnum.getByCode(productDetailDO.getStoreConditionType()))) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_DETAIL_NULL);
        }
        //2.是否有推广信息
        if (StringUtils.isBlank(productDetailDO.getRecommend())) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_DETAIL_NULL);
        }
        //3.是否有销售信息
        if (Objects.isNull(productDetailDO.getBasePrice()) || Objects.isNull(productDetailDO.getVipPrice())) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_DETAIL_NULL);
        }
        //4.验证商品是否品控信息完整
        List<QualityControlDO> qualityControlList = getQualityControlList(productDetailDO.getItemId());
        if (CollectionUtils.isEmpty(qualityControlList)) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_DETAIL_NULL);
        }
        //5.是否有图文信息(必须包含1-主图,2-轮播图、3-详情图)
        List<ItemVideoImgDO> itemVideoImgList = getItemVideoImgList(productDetailDO.getItemId());
        //先过滤掉不需要的图文信息
        List<ItemVideoImgDO> videoImgDOList = itemVideoImgList.stream().filter(itemVideoImgDO -> {
            if (ProductConstants.PRODUCT_IMG_TYPE_LIST.contains(itemVideoImgDO.getContentType())) {
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        //空验证
        if (CollectionUtils.isEmpty(itemVideoImgList)) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_DETAIL_NULL);
        }
        //获取图文集合类型
        Set<Integer> contentTypeList = videoImgDOList.stream().map(ItemVideoImgDO::getContentType).collect(Collectors.toSet());
        //过滤掉不符合的图片类型后,去重后,剩余的图片类型要和存储的一样多
        if (contentTypeList.size() != ProductConstants.PRODUCT_IMG_TYPE_LIST.size()) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_DETAIL_NULL);
        }
    }
    ...
}

二.商品试销上架时补充扩展属性和变更商品状态

//试销上架状态变更
@Service("trialSaleStatus")
public class TrialSaleStatusService extends AbstractStatusStrategy {
    ...
    //填充 试销商品的扩展字段(试销期截止时间)
    private void buildAttributeContent(ProductDetailDO productDetailDO) {
        //1.只有普通商品或者组套商品才处理扩展信息的变化
        if (checkItemType(productDetailDO)) {
            //获取试销期截止时间
            String trialSaleTime = DateFormatUtil.getDate(dateNum);
            //先获取到试销商品的原有扩展字段
            AttributeExtendDO attributeExtend = productStatusRepository.getAttributeExtend(productDetailDO.getItemId());
            AttributeExtendBO attributeExtendBO = null;
            //没有已经存在的扩展信息
            if (!Objects.isNull(attributeExtend) || StringUtils.isBlank(attributeExtend.getAttributeContent())) {
                attributeExtendBO = new AttributeExtendBO();
            } else {
                attributeExtendBO = JsonUtil.json2Object(attributeExtend.getAttributeContent(), AttributeExtendBO.class);
            }
            attributeExtendBO.setTrialSaleTime(trialSaleTime);
            //字段存储起来
            productDetailDO.setAttributeContent(JSONObject.toJSONString(attributeExtendBO));
        }
    }
    
    //变更商品的状态
    private void updateProduct(ProductDetailDO productDetailDO, ProductStatusRequest productStatusRequest) {
        ItemInfoDO itemInfoDO = productConverter.converterDO(productDetailDO);
        //更新商品状态
        productStatusRepository.updateProductStatus(itemInfoDO, productStatusRequest.getItemStatus());
        if (checkItemType(productDetailDO)) {
            //更新商品扩展信息
            productStatusRepository.updateAttributeExtend(productDetailDO);
        }
    }
    ...
}

@Repository
public class ProductStatusRepository {
    ...
    //更新商品状态
    public void updateProductStatus(ItemInfoDO itemInfoDO, Integer updateItemStatus) {
        LambdaUpdateWrapper<ItemInfoDO> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(ItemInfoDO::getItemId, itemInfoDO.getItemId());
        updateWrapper.eq(ItemInfoDO::getItemStatus, itemInfoDO.getItemStatus());
        updateWrapper.set(ItemInfoDO::getItemStatus, updateItemStatus);
        int count = itemInfoMapper.update(updateWrapper.getEntity(), updateWrapper);
        if (count <= 0) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_SQL);
        }
    }
    
    //更新商品的扩展信息
    public void updateAttributeExtend(ProductDetailDO productDetailDO) {
        LambdaUpdateWrapper<AttributeExtendDO> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(AttributeExtendDO::getParticipateId, productDetailDO.getItemId());
        updateWrapper.eq(AttributeExtendDO::getParticipateType, ProductTypeEnum.ITEM.getCode());
        updateWrapper.set(AttributeExtendDO::getAttributeContent, productDetailDO.getAttributeContent());
        int count = attributeExtendMapper.update(updateWrapper.getEntity(), updateWrapper);
        if (count <= 0) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_SQL);
        }
    }
    ...
}

(2)商品上架与预下架状态流转实现

//预下架状态变更
@Service("advanceShelvesStatus")
public class AdvanceShelvesStatusService extends AbstractStatusStrategy {
    @Autowired
    private ProductStatusRepository productStatusRepository;
    
    @Autowired
    private ProductConverter productConverter;

    //上架状态变更到预下架
    @Override
    public void updateProductStatus(ProductStatusRequest productStatusRequest) {
        //1.验证商品和前台类目绑定关系,绑定关系有效
        checkFrontCategoryList(productStatusRequest.getItemId());
        //2.验证商品数据是否完整
        ProductDetailDO productDetailDO = checkProductInfo(productStatusRequest.getItemId());
        //3.变更商品信息
        updateProduct(productDetailDO, productStatusRequest);
    }
    
    //查询商品是否和前台类目存在绑定关系
    private void checkFrontCategoryList(String itemId) {
        //获取类目绑定关系
        List<FrontCategoryRelationDO> frontCategoryRelationList = productStatusRepository.queryFrontCategoryList(itemId);
        //过滤状态,只保留有效的
        List<FrontCategoryRelationDO> categoryRelationDOList = frontCategoryRelationList.stream().filter(frontCategoryRelationDO -> {
            if (frontCategoryRelationDO.getDelFlag().equals(DelFlagEnum.EFFECTIVE.getCode())) {
                return true;
            }
            return false;
        }).collect(Collectors.toList());
        //商品不存在有效的绑定关系,提示错误
        if (CollectionUtils.isEmpty(categoryRelationDOList)) {
            throw new BaseBizException(ProductExceptionCode.PRODUCT_CATEGORY_RELATION_NULL);
        }
    }
    
    //验证商品的数据完整性
    private ProductDetailDO checkProductInfo(String itemId) {
        //查询商品的详情信息
        ProductDetailDO productDetailDO = productStatusRepository.queryProductDetail(itemId);
        //验证商品完整性
        productStatusRepository.checkProductComplete(productDetailDO);
        return productDetailDO;
    }
    
    //变更商品的状态
    private void updateProduct(ProductDetailDO productDetailDO, ProductStatusRequest productStatusRequest) {
        ItemInfoDO itemInfoDO = productConverter.converterDO(productDetailDO);
        productStatusRepository.updateProductStatus(itemInfoDO, productStatusRequest.getItemStatus());
    }
    ...
}

(3)商品下架和停售状态流转实现

//下架状态变更
@Service("offShelvesSaleStatus")
public class OffShelvesStatusService extends AbstractStatusStrategy {
    @Autowired
    private ProductStatusRepository productStatusRepository;
    
    @Autowired
    private ProductInfoRepository productInfoRepository;
    
    //上架状态 变更到下架状态
    //预上架状态 变更到下架状态
    @Override
    public void updateProductStatus(ProductStatusRequest productStatusRequest) {
        //1.查询商品信息
        ItemInfoDO itemInfoDO = productInfoRepository.getItemByItemId(productStatusRequest.getItemId());
        //2.商品状态变更
        productStatusRepository.updateProductStatus(itemInfoDO, productStatusRequest.getItemStatus());
    }
}

//停售状态
@Service("stopStatus")
public class StopStatusService extends AbstractStatusStrategy {
    @Autowired
    private ProductStatusRepository productStatusRepository;
    
    @Autowired
    private ProductInfoRepository productInfoRepository;
    
    //下架状态 变更到停售
    @Override
    public void updateProductStatus(ProductStatusRequest productStatusRequest) {
        //1.查询商品信息
        ItemInfoDO itemInfoDO = productInfoRepository.getItemByItemId(productStatusRequest.getItemId());
        //2.商品状态变更
        productStatusRepository.updateProductStatus(itemInfoDO, productStatusRequest.getItemStatus());
    }
}

(4)流转到上架的状态变更

//上架状态变更
@Service("shelvesSaleStatus")
public class ShelvesStatusService extends AbstractStatusStrategy {
    @Autowired
    private ProductConverter productConverter;
    
    @Autowired
    private ProductStatusRepository productStatusRepository;

    //准备上架状态 流转到上架
    //试销上架状态 流转到上架
    @Override
    public void updateProductStatus(ProductStatusRequest productStatusRequest) {
        //1.验证商品和前台类目绑定关系,绑定关系有效
        checkFrontCategoryList(productStatusRequest.getItemId());
        //2.验证商品数据是否完整
        ProductDetailDO productDetailDO = checkProductInfo(productStatusRequest.getItemId());
        //3.变更商品信息
        updateProduct(productDetailDO, productStatusRequest);
    }
    ...
}

后端技术栈的基础修养 文章被收录于专栏

详细介绍后端技术栈的基础内容,包括但不限于:MySQL原理和优化、Redis原理和应用、JVM和G1原理和优化、RocketMQ原理应用及源码、Kafka原理应用及源码、ElasticSearch原理应用及源码、JUC源码、Netty源码、zk源码、Dubbo源码、Spring源码、Spring Boot源码、SCA源码、分布式锁源码、分布式事务、分库分表和TiDB、大型商品系统、大型订单系统等

全部评论

相关推荐

06-19 14:58
门头沟学院 Java
点赞 评论 收藏
分享
04-29 22:35
门头沟学院 Java
牛友说改了名字能收到offer:旧图新发查看图片
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务