谷粒商城--SPU和SKU(属性分组、规格参数、销售属性)-2

简介: 谷粒商城--SPU和SKU(属性分组、规格参数、销售属性)

规格参数详情

接口如下:

7797f3f5e440b6e01b7bb89e1b1a3653_7b7e1e648fd3233d1cb655bd1688689b.png


什么是规格参数?


34e5c3bc390d5b8d08a4d6332e57e6a4_d49d18ad35c2fab16652e9a7e7ef05d3.png


保存规格参数

controller

/**
 * 保存
 */
@RequestMapping("/save")
public R save(@RequestBody AttrVo vo){
  attrService.saveAttr(vo);
    return R.ok();
}

service


这里注意,因为添加规格参数的时候会有选择属性组,因为属性组和属性是通过关联关系表连接的所以要有级联操作。


在往pms_attr表插入数据的时候,pms_attr_group_relation也要插入


小bug:这里有个注意点,当添加规格参数的时候如果没有指定规格参数所属分组,那么就不应该在关联表中保存关联关系!!!


@Override
public void saveAttr(AttrVo attr) {
    AttrEntity attrEntity = new AttrEntity();
    //1.将前端接收数据的对象vo赋值给attrEntity对象,从而更新数据库
    BeanUtils.copyProperties(attr, attrEntity);
    this.save(attrEntity);
    if (attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && attr.getAttrGroupId() != null) {
        //2.保存关联关系
        //因为属性组和属性是通过关联关系表连接的
        AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
        relationEntity.setAttrGroupId(attr.getAttrGroupId());
        relationEntity.setAttrId(attrEntity.getAttrId());
        relationService.save(relationEntity);
    }
}

显示规格参数

controller


/**
 * 显示规格参数
 */
@GetMapping("/base/list/{catelogId}")
public R baseAttrList(@RequestParam Map<String, Object> params,
                      @PathVariable("catelogId") Integer catelogId) {
    PageUtils page = attrService.queryBaseAttrPage(params, catelogId);
    return R.ok().put("page", page);
}

service

//分页查询规格参数
@Override
public PageUtils queryBaseAttrPage(Map<String, Object> params, Integer catelogId) {
    QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>();
    if (catelogId != 0) {
        //如果不是一级分类,那么查询的时候加上where catelog_id = ?
        wrapper.eq("catelog_id", catelogId);
    }
    //多条件模糊查询
    //搜索框里的key不但可以对catelog_id进行模糊查询,对attr_name也模糊查询
    String key = (String) params.get("key");
    if (!StringUtils.isEmpty(key)) {
        wrapper.eq("attr_id", key).or().like("attr_name", key);
    }
    //多条件分页查询
    IPage<AttrEntity> page = this.page(
        new Query<AttrEntity>().getPage(params),
        wrapper);
    PageUtils pageUtils = new PageUtils(page);
    return pageUtils;
}

测试


如下:


87d25279ab828aed49074d75f5551135_ff296593d530fd1ff3eaef526b7562ea.png


这些属性的分类和所属分组怎么查呢?


规格参数表(pms_attr)中,有所属分类的信息,可以直接调用分类的service进行查询


那分组信息怎么查询呢?规格参数表中没有所属分类相关的信息…


这里我们就要借助第三张表,属性和分组表(pms_attr_attrgroup_relation)进行查询


通过规格参数表(pms_attr)获得attr_id,之后在调用属性和分组表的service获得属性和分组表的实体类,从而获得该属性的分组


下面通过stream流的方式,通过map给list集合中的每一项做映射给新实体类(AttrRespVo)赋值,最后返回AttrRespVo


小bug:这里显示规格参数的时候,会显示规格。参数对应的分组、分类,那么如果它们查出对象分组id或分类id为空那就不设置名字if (attrId != null && attrId.getAttrGroupId() != null) {…}


//分页查询规格参数
@Override
public PageUtils queryBaseAttrPage(Map<String, Object> params, String type, Integer catelogId) {
    QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>()
        .eq("attr_type", "base".equalsIgnoreCase(type) ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
    if (catelogId != 0) {
        //如果不是一级分类,那么查询的时候加上where catelog_id = ?
        //IgnoreCase忽略大小写
        wrapper.eq("catelog_id", catelogId);
    }
    //多条件模糊查询
    //搜索框里的key不但可以对catelog_id进行模糊查询,对attr_name也模糊查询
    String key = (String) params.get("key");
    if (!StringUtils.isEmpty(key)) {
        wrapper.eq("attr_id", key).or().like("attr_name", key);
    }
    //多条件分页查询
    IPage<AttrEntity> page = this.page(
        new Query<AttrEntity>().getPage(params),
        wrapper);
    PageUtils pageUtils = new PageUtils(page);
    List<AttrEntity> list = page.getRecords();
    //        .map()这个方法是对被筛选过后的流进行映射,一般是对属性进行赋值。
    List<AttrRespVo> resultList = list.stream().map(item -> {
        AttrRespVo attrRespvo = new AttrRespVo();
        BeanUtils.copyProperties(item, attrRespvo);
        //设置分类和分组的名字
        if ("base".equalsIgnoreCase(type)) {
            AttrAttrgroupRelationEntity attrId = relationService.
                getOne(new QueryWrapper<AttrAttrgroupRelationEntity>()
                       .eq("attr_id", item.getAttrId()));
            if (attrId != null && attrId.getAttrGroupId() != null) {
                //attrgroupRelationEntity.getAttrGroupId()也可以,这里可以直接放进去对象
                AttrGroupEntity attrGroupEntity = attrGroupService.getById(attrId.getAttrGroupId());
                attrRespvo.setGroupName(attrGroupEntity.getAttrGroupName());
            }
        }
        CategoryEntity categoryEntity = categoryService.getById(item.getCatelogId());
        if (categoryEntity != null) {
            attrRespvo.setCatelogName(categoryEntity.getName());
        }
        //返回最后的封装结果
        return attrRespvo;
    }).collect(Collectors.toList());
    //返回的结果是一个集合
    pageUtils.setList(resultList);
    //        返回分页后的集合对象
    return pageUtils;
}

AttrRespVo


@Data
public class AttrRespVo extends AttrVo {
    private String catelogName;
    private String  groupName;
}

测试


06be5ea8dc115b32c5b06d131f876ecc_a2a6b7da6c0afa6d9c06d8f6bdbdd537.png


规格参数回显

可以看出所属分类和分组都是由这条请求查询的,那么我们改这个接口功能就行


相当于在原来查询基础上返回分类路径信息,分组信息


c1987704e4055866eee50a78cb5bf23c_a8ae8980e4f6322397de7a54251b18ab.png


controller

/**
 * 信息
 */
@RequestMapping("/info/{attrId}")
public R info(@PathVariable("attrId") Long attrId) {
    AttrRespVo respVo = attrService.getAttrInfo(attrId);
    return R.ok().put("attr", respVo);
}

service


@Override
public AttrRespVo getAttrInfo(Long attrId) {
    AttrRespVo respVo = new AttrRespVo();
    AttrEntity attrEntity = this.getById(attrId);
    BeanUtils.copyProperties(attrEntity, respVo);
    /**
     * 设置分组信息
     */
    AttrAttrgroupRelationEntity attrgroupRelationEntity = relationService.
            getOne(new QueryWrapper<AttrAttrgroupRelationEntity>()
                    .eq("attr_id", attrEntity.getAttrId()));
    if (attrgroupRelationEntity != null){
        respVo.setAttrGroupId(attrgroupRelationEntity.getAttrGroupId());
        Long attrGroupId = attrgroupRelationEntity.getAttrGroupId();
        AttrGroupEntity attrGroupEntity = attrGroupService.getById(attrGroupId);
        if (attrGroupEntity != null) {
            respVo.setGroupName(attrGroupEntity.getAttrGroupName());
        }
    }
    /**
     * 设置分类信息
     */
    Long catelogId = attrEntity.getCatelogId();
    //有了分类的完整路径,接下来就设置分类名字
    Long[] catelogPath = categoryService.findCatelogPath(catelogId);
    respVo.setCatelogPath(catelogPath);
    //获得分类名字
    CategoryEntity categoryEntity = categoryService.getById(catelogId);
    if (categoryEntity != null) {
        respVo.setCatelogName(categoryEntity.getName());
    }
    return respVo;
}

测试


205ec1e44942181bf2e92c20ff80ae19_389a62f9bac93bd2fb14d5d40f0cd3e2.png


修改Or增加

提交修改分类和分组是无效的?


更改用的还是默认的update方法,所以我们改update接口!


8b4ff92e94cd600ebf3cc7eb9bce9df6_9771230c7e7475cd81566bb7bb82e702.png


controller


/**
 * 修改
 */
@RequestMapping("/update")
public R update(@RequestBody AttrVo attr) {
    attrService.updateAttr(attr);
    return R.ok();
}

service


这里做了优化,对于规格参数中没有所属分组的,如果指定了不在是修改而是添加!


怎么判断规格参数有没有所属分组呢?


拿attr_id去pms_attr_attrgroup_relation表中查询,如果改attr_id存在与该表,那就修改关联关系


如果没有数据,那么就在此表添加数据!

@Transactional
@Override
public void updateAttr(AttrVo attr) {
    AttrEntity attrEntity = new AttrEntity();
    BeanUtils.copyProperties(attr, attrEntity);
    this.updateById(attrEntity);
    //修改分组关联
    AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
    attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
    attrAttrgroupRelationEntity.setAttrId(attr.getAttrId());
    //统计attr_id的关联属性,如果没有初始分组,则进行添加操作;有则进行修改操作
    Integer count = relation.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
    if (count > 0) {
        relation.update(attrAttrgroupRelationEntity, new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
    } else {
        relation.insert(attrAttrgroupRelationEntity);
    }
}

spu规格维护

出现400页面,在数据库添加


INSERT INTO sys_menu (menu_id, parent_id, name, url, perms, type, icon, order_num) VALUES (76, 37, '规格维护', 'product/attrupdate', '', 2, 'log', 0);
更新index.js,哪里更新?找老师的源码

controller


@PostMapping("/update/{spuId}")
public R updateSpuAttr(@PathVariable("spuId") Long spuId,
                       @RequestBody List<ProductAttrValueEntity> entities){
    productAttrValueService.updateSpuAttr(spuId,entities);
    return R.ok();
}

impl


这里的修改其实是先把原来的spu_id下的属性都删除掉


之后在把前端传来的属性集合进行批量保存


@Transactional(rollbackFor = Exception.class)
@Override
public void updateSpuAttr(Long spuId, List<ProductAttrValueEntity> entities) {
    //1、删除spuId之前对应的所有属性
    this.baseMapper.delete(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id",spuId));
    //2、添加商品规格信息
    List<ProductAttrValueEntity> collect = entities.stream().map(item -> {
        item.setSpuId(spuId);
        return item;
    }).collect(Collectors.toList());
    //批量新增
    this.saveBatch(collect);
}

销售属性详情

显示销售属性

如图http://localhost:88/api/product/attr/sale/list/0?t=1660181297434&page=1&limit=10&key=这个接口有问题!


所以我们就去后端改这个接口即可!


5836f39d798e2fd94ffd0bf6ec2c98d7_74ef8de982ed8badfae0452f81516775.png


controller


规格参数和销售参数的区别在于type的值,type为 1是规格参数,type为0是销售参数


这里采用一个方法当两个来用!


dcd15aa3b28c039312b0cf06378f373c_ca5be51f611f8409a7e4970138620a46.png


@GetMapping("/{attrType}/list/{catelogId}")
public R baseAttrList(@RequestParam Map<String, Object> params,
                      @PathVariable("attrType") String type,
                      @PathVariable("catelogId") Integer catelogId) {
    PageUtils page = attrService.queryBaseAttrPage(params, type, catelogId);
    return R.ok().put("page", page);
}

service


在原来对规格参数的基础上加了限制条件,如果是规格参数那就是WHERE attr_type = 1,否则就是WHERE attr_type = 0;


下面的逻辑和查询规格参数一致,都要模糊查询


这里为了使代码更通用,1和0的值我们写一个常量来控制,如过后期换值了我们直接更改常量的值即可


ProductConstant


package com.caq.common.constant;
public class ProductConstant {
    public enum AttrEnum{
        ATTR_TYPE_BASE(1,"基本属性"),
        ATTR_TYPE_SALE(0,"销售属性");
        private int code;
        private String msg;
        AttrEnum(int code,String msg){
            this.code = code;
            this.msg = msg;
        }
        public int getCode(){
            return code;
        }
        public String getMsg(){
            return msg;
        }
    }
}

在原来对规格参数的基础上加了限制条件,如果是规格参数那就是WHERE attr_type = 1,否则就是WHERE attr_type = 0;


@Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, String type, Integer catelogId) {
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>()
                .eq("attr_type", "base".equalsIgnoreCase(type) ? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() : ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
        if (catelogId != 0) {
            //如果不是一级分类,那么查询的时候加上where catelog_id = ?
            //IgnoreCase忽略大小写
            wrapper.eq("catelog_id", catelogId);
        }
        //多条件模糊查询
        //搜索框里的key不但可以对catelog_id进行模糊查询,对attr_name也模糊查询
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.eq("attr_id", key).or().like("attr_name", key);
        }
        //多条件分页查询
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper);
        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> list = page.getRecords();
//        .map()这个方法是对被筛选过后的流进行映射,一般是对属性进行赋值。
        List<AttrRespVo> resultList = list.stream().map(item -> {
            AttrRespVo attrRespvo = new AttrRespVo();
            BeanUtils.copyProperties(item, attrRespvo);
            AttrAttrgroupRelationEntity attrgroupRelationEntity = relationService.
                    getOne(new QueryWrapper<AttrAttrgroupRelationEntity>()
                            .eq("attr_id", item.getAttrId()));
            if (attrgroupRelationEntity != null) {
                //attrgroupRelationEntity.getAttrGroupId()也可以,这里可以直接放进去对象
                AttrGroupEntity attrGroupEntity = attrGroupService.getById(attrgroupRelationEntity);
                attrRespvo.setGroupName(attrGroupEntity.getAttrGroupName());
            }
            CategoryEntity categoryEntity = categoryService.getById(item.getCatelogId());
            if (categoryEntity != null) {
                attrRespvo.setCatelogName(categoryEntity.getName());
            }
            //返回最后的封装结果
            return attrRespvo;
        }).collect(Collectors.toList());
        //返回的结果是一个集合
        pageUtils.setList(resultList);
//        返回分页后的集合对象
        return pageUtils;
    }

销售属性回显

可以看到,销售属性回显是不需要所属分组的


但是销售属性和规格参数用的是同一个回显方法,我们也进行更改,只有是规格参数的时候才进行分组回显!


6c392e1eb2f105072f783fff8c01675a_a385d747bab5c37a25f3eea078ebdc27.png


在原分组回显的逻辑上加上判断,后面逻辑不变!


if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
    ...
}

2856a9a4af5c3826edc1f128bf7abf34_610c7bbd019d784ec179c79f8cdc31e1.png


修改销售属性

销售属性和规格参数用的是同一个修改方法,销售属性进行修改时,会对关联表进行一个级联更新,但销售属性不需要


所以也在对关联表级联更新的时候进行判断,只有销售属性修改的时候才进行级联更新!


if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
    ...
}

7c332805934ae93f1d06c843b51d14a2_dd659e254b74ca3c18ec218d35f51c69.png


保存销售属性

销售属性和规格参数用的是同一个保存方法,销售属性进行保存时,会对关联表进行一个级联保存,但销售属性不需要


所以也在对关联表级联保存的时候进行判断,只有销售属性保存的时候才进行级联保存!


if (attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()) {
    ...
}

93db0a36e9b9d6a06b2ee93613fbaf62_96c8f6eaa690c15c185b9dcdeadbbe60.png

相关文章
|
28天前
|
存储 数据采集 JSON
电商API分享:如何批量获取商品详情页数据(属性图价格sku视频评论)
电商API(应用程序接口)通常提供了丰富的数据获取功能,使开发者能够方便地获取商品详情页的各种数据,包括商品属性、图片、价格、SKU(库存量单位)、视频以及评论等。以下是一个基本的步骤指南,用于通过电商API批量获取商品详情页数据:
|
8月前
|
XML JSON 缓存
Java实现根据商品ID请求京东工业商品详情数据方法
Java实现根据商品ID请求京东工业商品详情数据方法
69 0
|
5月前
|
SQL 前端开发 测试技术
谷粒商城--SPU和SKU(属性分组、规格参数、销售属性)-1
谷粒商城--SPU和SKU(属性分组、规格参数、销售属性)
102 0
|
5月前
|
测试技术 API 微服务
谷粒商城--SPU和SKU(分组与属性关联、发布商品、仓库服务)-3
谷粒商城--SPU和SKU(分组与属性关联、发布商品、仓库服务)
33 0
|
5月前
|
JSON 前端开发 Java
谷粒商城--SPU和SKU(分组与属性关联、发布商品、仓库服务)-2
谷粒商城--SPU和SKU(分组与属性关联、发布商品、仓库服务)
41 0
|
5月前
|
JSON 数据格式
谷粒商城--SPU和SKU(分组与属性关联、发布商品、仓库服务)-1
谷粒商城--SPU和SKU(分组与属性关联、发布商品、仓库服务)
27 0
|
7月前
|
API
电商API接口开发系列-商品采集接口、关键字搜索接口,获取商品ID、商品主图接口
目前各大电商平台都有自己的开放平台,通过API接口开放本电商平台的相关数据和功能,以自由开放的姿态来占领更多的市场份额。也让更多的人能来电商市场分得一杯羹。 通过电商API接口可以实现获取电商平台商品数据、订单数据、上下架商品、批量处理订单、批量发货、批量购买、买家信息、卖家信息等等功能。
电商API接口开发系列-商品采集接口、关键字搜索接口,获取商品ID、商品主图接口
|
9月前
|
XML JSON 缓存
Java实现商品ID获取淘宝商品SKU属性数据方法
Java实现商品ID获取淘宝商品SKU属性数据方法
113 0
|
9月前
|
XML JSON 缓存
Java实现商品ID获取京东商品详情Desc商品描述数据方法
Java实现商品ID获取京东商品详情Desc商品描述数据方法
57 0
|
9月前
|
XML JSON 缓存
Java实现商品ID获取淘宝商品类目数据方法
Java实现商品ID获取淘宝商品类目数据方法
93 0

热门文章

最新文章