商品中心—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);
    }
    ...
}
相关推荐
东阳马生架构1 天前
商品中心—19.库存分桶高并发的优化文档
商品系统
东阳马生架构11 天前
商品中心—11.商品B端搜索系统的实现文档一
商品系统
东阳马生架构11 天前
商品中心—12.商品溯源系统的技术文档
商品系统
东阳马生架构12 天前
商品中心—11.商品B端搜索系统的实现文档
商品系统
东阳马生架构12 天前
商品中心—10.商品B端搜索系统的说明文档
商品系统
东阳马生架构15 天前
商品中心—9.商品卖家系统的技术文档
商品系统
东阳马生架构16 天前
商品中心—8.商品C端处理高并发的技术文档
商品系统
东阳马生架构21 天前
商品中心—1.B端建品和C端缓存的技术文档一
缓存·商品系统