石娅凉 发表于 2025-6-12 09:40:53

商品中心—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 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 = "操作人不能为空")
    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 saveAttributeValue(List 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 list) {
      attributeRepository.saveAttributeValues(list);
      return new AttributeValueResultDTO(true);
    }
    ...
}

//属性库
@Repository
public class AttributeRepository {
    @Resource
    private AttributeValueMapper attributeValueV2Mapper;
    ...
   
    //批量保存属性值
    public void saveAttributeValues(List list) {
      //先删
      LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
      queryWrapper.eq(AttributeValueDO::getAttributeId, list.get(0).getAttributeId());
      attributeValueV2Mapper.delete(queryWrapper);
      //后保存
      List 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);
      }
    }
    ...

7.商品属性库系统与商品M端系统对接
//属性管理相关操作API
@DubboService(version = "1.0.0", interfaceClass = AttributeApi.class, retries = 0)
public class AttributeApiImpl implements AttributeApi {
    ...
    @Autowired
    private AttributeService attributeService;
   
    //添加属性组接口
    @Override
    public JsonResult 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();
    }
    ...

8.商品状态变更流转架构设计
(1)状态流转策略表
(2)商品状态变更流向图
(3)接口实现流程图
 
(1)状态流转策略表
//属性管理相关操作API
@DubboService(version = "1.0.0", interfaceClass = AttributeApi.class, retries = 0)
public class AttributeApiImpl implements AttributeApi {
    ...
    @Autowired
    private AttributeService attributeService;
   
    //添加属性模板接口
    @Override
    public JsonResult saveAttributeTemplate(AttributeTemplateRequest request) {
      AttributeTemplateResultDTO attributeTemplateResultDTO = attributeService.saveAttributeTemplate(request);
      return JsonResult.buildSuccess(attributeTemplateResultDTO);
    }
   
    //给模板添加模板内容接口
    @Override
    public JsonResult saveAttributeTemplateContents(List 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 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 list) {
      //先删
      LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
      queryWrapper.eq(AttributeTemplateContentDO::getTemplateId, list.get(0).getTemplateId());
      attributeTemplateContentMapper.delete(queryWrapper);
      //后保存
      List 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);
      }
    }
    ...
}(2)商品状态变更流向图
说明:严格按照箭头方向执行,除了可重新上架,其他状态变更均不可逆。
(3)接口实现流程图
 
9.商品状态变更流转的策略模式实现
具体实现在商品M端系统:
一.验证⼊参必填(商品ID和变更状态)
二.验证商品是否存在,停售状态禁⽌变更状态
三.获取状态流转策略表,根据商品的当前状态和变更状态获取配置的映射策略类的实例名称
四.实现关于每个状态变更的具体逻辑
//属性管理相关操作API
@DubboService(version = "1.0.0", interfaceClass = AttributeApi.class, retries = 0)
public class AttributeApiImpl implements AttributeApi {
    ...
    @Autowired
    private AttributeService attributeService;
   
    //属性分页查询接口
    @Override
    public JsonResult<PageResult> pageAttributeInfo(QueryAttributeInfoRequest request) {
      PageResult pageResult = attributeService.pageAttributeInfo(request);
      return JsonResult.buildSuccess(pageResult);
    }
   
    //根据属性id查询属性及可选的属性值
    @Override
    public JsonResult<List> queryAttributeValueByAttributeId(Long attributeId) {
      List attributeValueDTOS = attributeService.queryAttributeValueByAttributeId(attributeId);
      return JsonResult.buildSuccess(attributeValueDTOS);
    }
   
    //属性组分页查询接口
    @Override
    public JsonResult<PageResult> pageAttributeGroup(QueryAttributeGroupRequest request) {
      PageResult pageResult = attributeService.pageAttributeGroup(request);
      return JsonResult.buildSuccess(pageResult);
    }
   
    //属性模板分页查询接口
    @Override
    public JsonResult<PageResult> pageAttributeTemplate(QueryAttributeTemplateRequest request) {
      PageResult pageResult = attributeService.pageAttributeTemplate(request);
      return JsonResult.buildSuccess(pageResult);
    }
   
    //根据模板id查询模板内容接口
    @Override
    public JsonResult<List> queryAttributeTemplateContentByTemplateId(Long templateId) {
      List attributeTemplateContentDTOS = attributeService.queryAttributeTemplateContentByTemplateId(templateId);
      return JsonResult.buildSuccess(attributeTemplateContentDTOS);
    }
    ...
}

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

//属性库
@Repository
public class AttributeRepository {
    @Resource
    private AttributeGroupMapper attributeGroupMapper;
   
    //分页查询属性
    public PageResult pageAttributeInfo(QueryAttributeInfoRequest request) {
      LambdaQueryWrapper 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 page = new Page<>(request.getPageNum(), request.getPageSize());
      Page pageResult = attributeInfoMapper.selectPage(page, queryWrapper);
      return attributeConverter.convertAttributeInfoDTOPageResult(pageResult);
    }
   
    //根据属性id查询属性值
    public List queryAttributeValueByAttributeId(Long attributeId) {
      LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
      queryWrapper.eq(AttributeValueDO::getAttributeId, attributeId);
      List attributeValueDOS = attributeValueV2Mapper.selectList(queryWrapper);
      return attributeConverter.convertAttributeValueV2DTOList(attributeValueDOS);
    }
   
    //分页查询属性组
    public PageResult pageAttributeGroup(QueryAttributeGroupRequest request) {
      LambdaQueryWrapper 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 page = new Page<>(request.getPageNum(), request.getPageSize());
      Page pageResult = attributeGroupMapper.selectPage(page, queryWrapper);
      return attributeConverter.convertAttributeGroupDTOPageResult(pageResult);
    }
   
    //分页查询属性模板
    public PageResult pageAttributeTemplate(QueryAttributeTemplateRequest request) {
      LambdaQueryWrapper 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 page = new Page<>(request.getPageNum(), request.getPageSize());
      Page pageResult = attributeTemplateMapper.selectPage(page, queryWrapper);
      return attributeConverter.convertAttributeTemplateDTOPageResult(pageResult);
    }
   
    //根据属性模板id查询属性模板内容
    public List queryAttributeTemplateContentByTemplateId(Long templateId) {
      LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
      queryWrapper.eq(AttributeTemplateContentDO::getTemplateId, templateId);
      List attributeTemplateContentDOS = attributeTemplateContentMapper.selectList(queryWrapper);
      return attributeConverter.convertAttributeTemplateContentDTOList(attributeTemplateContentDOS);
    }   
    ...

10.商品状态变更流转的具体策略实现
(1)商品试销上架的实现
(2)商品上架与预下架状态流转实现
(3)商品下架和停售状态流转实现
(4)流转到上架的状态变更
 
(1)商品试销上架的实现
一.商品试销上架时对前端销售数据校验
//商品属性相关操作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 attributeTemplateContentDTOS = attributeRepository.queryAttributeTemplateContentByTemplateId(templateId);
      //4.查询出相关的属性组
      List<Long> groupIds = attributeTemplateContentDTOS.stream()
            .map(AttributeTemplateContentDTO::getGroupId)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
      List 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 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 queryAttributeTemplateContentByTemplateId(Long templateId) {
      LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
      queryWrapper.eq(AttributeTemplateContentDO::getTemplateId, templateId);
      List attributeTemplateContentDOS = attributeTemplateContentMapper
            .selectList(queryWrapper);
      return attributeConverter.convertAttributeTemplateContentDTOList(attributeTemplateContentDOS);
    }
   
    //根据id批量查询属性组
    public List queryGroups(List<Long> groupIds) {
      List attributeGroupDOS = attributeGroupMapper.selectBatchIds(groupIds);
      return attributeConverter.convertAttributeGroupDTOList(attributeGroupDOS);
    }
   
    //根据id批量查询属性
    public List queryAttributeInfos(List<Long> attributeIds) {
      List 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());
    }
    ...
}二.商品试销上架时补充扩展属性和变更商品状态
//试销上架状态变更@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);      }    }    ...}@Repositorypublic class ProductStatusRepository {    ...    //更新商品状态    public void updateProductStatus(ItemInfoDO itemInfoDO, Integer updateItemStatus) {      LambdaUpdateWrapper 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
页: [1]
查看完整版本: 商品中心—4.商品属性与状态流转的技术文档