谷粒商城-day12-平台属性

属性分组查询调整

谷粒商城-day12-平台属性_第1张图片
@Override
public PageUtils queryPage(Map<String, Object> params, Long catelogId) {
    String key = (String) params.get("key");
    // select * from pms_attr_group where catelog_id = ? and (attr_group_id=key or attr_group_name like %key%)
    QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<AttrGroupEntity>();
    if (!StringUtils.isEmpty(key)){
        wrapper.and((obj)->{
            obj.eq("attr_group_id", key).or().like("attr_group_name", key);
        });
    }
    if (catelogId == 0) {
        IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params),
                wrapper);
        return new PageUtils(page);
    } else {
        wrapper.eq("catelog_id", catelogId);
        IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params),
                wrapper);
        return new PageUtils(page);
    }
}

测试

谷粒商城-day12-平台属性_第2张图片

查询所有现在也可以用模糊查询

属性分组关联

添加一个 attr-group-relation 组件

这里放在后面实现,我们先来处理规格参数和销售属性

谷粒商城-day12-平台属性_第3张图片

规则参数新增

属性这里新增时缺少分组信息的关联写入,重写save

谷粒商城-day12-平台属性_第4张图片
package com.zhouzhou.gulimall.product.entity.vo;


import lombok.Data;

@Data
public class AttrVo {
    /**
     * 属性id
     */
    private Long attrId;
    /**
     * 属性名
     */
    private String attrName;
    /**
     * 是否需要检索[0-不需要,1-需要]
     */
    private Integer searchType;
    /**
     * 属性图标
     */
    private String icon;
    /**
     * 可选值列表[用逗号分隔]
     */
    private String valueSelect;
    /**
     * 属性类型[0-销售属性,1-基本属性,2-既是销售属性又是基本属性]
     */
    private Integer attrType;
    /**
     * 启用状态[0 - 禁用,1 - 启用]
     */
    private Long enable;
    /**
     * 所属分类
     */
    private Long catelogId;
    /**
     * 快速展示【是否展示在介绍上;0-否 1-是】,在sku中仍然可以调整
     */
    private Integer showDesc;

    private Long attrGroupId;
}

谷粒商城-day12-平台属性_第5张图片

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody AttrVo attr){
		attrService.saveAttr(attr);

        return R.ok();
    }
    @Transactional
    @Override
    public void saveAttr(AttrVo attr) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attr, attrEntity);
//        1.保存基本数据
        this.save(attrEntity);
//        2. 保存关联关系
        AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
        relationEntity.setAttrGroupId(attr.getAttrGroupId());
        relationEntity.setAttrId(attrEntity.getAttrId());
        relationDao.insert(relationEntity);
    }
image-20210226171217853 谷粒商城-day12-平台属性_第6张图片

规格参数列表查询

  • 0 是查询所有

  • 带模糊查询功能

    这个功能其实和之前的实现是类似的

谷粒商城-day12-平台属性_第7张图片 谷粒商城-day12-平台属性_第8张图片
//    /product/attr/base/list/{catelogId}
    @GetMapping("/base/list/{catelogId}")
    public R baseAttrList(@RequestParam Map<String, Object> params, @PathVariable("catelogId") Long catelogId){
        PageUtils page = attrService.queryBaseAttrPage(params, catelogId);
        return R.ok().put("page", page);
    }


    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        if (catelogId != 0) {
         queryWrapper.eq("catelog_id", catelogId);
        }

        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)){
//            attr_id attr_name
            queryWrapper.and((wrapper)->{
               wrapper.eq("attr_id", key).or().like("attr_name", key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }
谷粒商城-day12-平台属性_第9张图片

返回加上 所属分类和所属分组

vo

@Data
public class AttrRespVo extends AttrVo{

    /**
     * catelogName: 手机/数码/手机 // 属性分组名称
     * groupName: 主体,// 分组名称
     */
    private String catelogName;

    private String groupName;
}

对分页后的数据进行处理,避免 left join 造成的计算量过大问题

@Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId) {
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
        if (catelogId != 0) {
         queryWrapper.eq("catelog_id", catelogId);
        }

        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)){
//            attr_id attr_name
            queryWrapper.and((wrapper)->{
               wrapper.eq("attr_id", key).or().like("attr_name", key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );
        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> records = page.getRecords();
        List<AttrRespVo> respVos = records.stream().map((attrEntity) -> {
            AttrRespVo attrRespVo = new AttrRespVo();
            BeanUtils.copyProperties(attrEntity, attrRespVo);

//            1.设置分类和分组的名字
            AttrAttrgroupRelationEntity attrId = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
            if (attrId != null) {
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrId.getAttrGroupId());
                attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
            }
            CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
            if (categoryEntity != null) {
                attrRespVo.setCatelogName(categoryEntity.getName());
            }

            return attrRespVo;
        }).collect(Collectors.toList());

        pageUtils.setList(respVos);
        return pageUtils;
    }
谷粒商城-day12-平台属性_第10张图片

规格修改

先来修改查询详情功能,目前没有回显,缺少 catelogPath 属性

谷粒商城-day12-平台属性_第11张图片 谷粒商城-day12-平台属性_第12张图片

修改 vo, 添加 catelogPath

@Data
public class AttrRespVo extends AttrVo{

    /**
     * catelogName: 手机/数码/手机 // 属性分组名称
     * groupName: 主体,// 分组名称
     */
    private String catelogName;

    private String groupName;

    private Long[] catelogPath;
}

service 查询重写

@Override
    public AttrRespVo getAttrInfo(Long attrId) {
        AttrRespVo respVo = new AttrRespVo();
        AttrEntity attrEntity = this.getById(attrId);
        BeanUtils.copyProperties(attrEntity, respVo);

        // 1.设置分组信息
        AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>()
                .eq("attr_id", attrId));
        if (relationEntity!=null) {
            respVo.setAttrGroupId(relationEntity.getAttrGroupId());
            AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
            if (attrGroupEntity!=null) {
                respVo.setGroupName(attrGroupEntity.getAttrGroupName());
            }
        }
        // 2. 设置分类信息
        Long catelogId = attrEntity.getCatelogId();
        Long[] catelogPath = categoryService.findCatelogPath(catelogId);
        respVo.setCatelogPath(catelogPath);

        CategoryEntity categoryEntity = categoryDao.selectById(catelogId);
        if (categoryEntity!=null) {
            respVo.setCatelogName(categoryEntity.getName());
        }

        return respVo;
    }

重写 update,和之前重写的save 思路一致

@Transactional
@Override
public void updateAttr(AttrVo attr) {
    AttrEntity attrEntity = new AttrEntity();
    BeanUtils.copyProperties(attr, attrEntity);
    this.updateById(attrEntity);
    //1.修改分组关联
    AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
    relationEntity.setAttrGroupId(attr.getAttrGroupId());
    relationEntity.setAttrId(attr.getAttrId());
    Integer count = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
    if (count>0) {
        relationDao.update(relationEntity, new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
    } else {
        relationDao.insert(relationEntity);
    }
}

销售属性维护

需求分析:销售属性和规格参数其实查询的是一张表,根据 type 来区分

谷粒商城-day12-平台属性_第13张图片

这里重写查询,把对 规格参数的查询和销售属性的查询合并到一起

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

用三元表达式把这里区分开

queryWrapper.eq("attr_type", "base".equalsIgnoreCase(type) ? 1 : 0);

加上判断条件,销售属性没有 分组数据

if ("base".equalsIgnoreCase(type)) {
                AttrAttrgroupRelationEntity attrId = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
                if (attrId != null) {
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrId.getAttrGroupId());
                    attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }

保存和修改以及查询详情时也添加分支区分,否则会创建销售属性时也创建和修改分组

//2.保存关联关系
        if (attr.getAttrType() == 1) {
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationEntity.setAttrGroupId(attr.getAttrGroupId());

            relationDao.insert(relationEntity);

            this.save(attrEntity);
        }
// 后面的对应修改下就好

枚举

package com.example.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;
        }
    }
}

验证,创建销售属性,不会在

attr_attrgroup 表中创建记录

分组与属性关联

获取属性分组的关联的所有属性

谷粒商城-day12-平台属性_第14张图片 谷粒商城-day12-平台属性_第15张图片
/**
 * 获取属性分组的关联的所有属性
 */
@GetMapping("/{attrgroupId}/attr/relation")
public R attrTelation(@PathVariable("attrgroupId") Long attrgroupId
) {
    List<AttrEntity> list = attrService.getRelationAttr(attrgroupId);

    return R.ok().put("data", list);
}

/**
 * 获取属性分组的关联的所有属性
 * @param attrgroupId
 * @return
 */
@Override
public List<AttrEntity> getRelationAttr(Long attrgroupId) {
        List<AttrAttrgroupRelationEntity> entities = relationDao.selectList(new  			    QueryWrapper<AttrAttrgroupRelationEntity>()
                .eq("attr_group_id", attrgroupId));

        List<Long> attrIds = entities.stream().map(attr -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());

        List<AttrEntity> groupEntities = this.listByIds(attrIds);

        return groupEntities;
    }

测试

谷粒商城-day12-平台属性_第16张图片

删除属性与分组的关联关系

谷粒商城-day12-平台属性_第17张图片

谷粒商城-day12-平台属性_第18张图片

vo

@Data
public class AttrGroupRelationVo {
    private Long attrId;
    private Long attrGroupId;
}
@PostMapping("/attr/relation/delete")
public R deleteRelation(AttrGroupRelationVo[] attrGroupRelationVos){
    attrService.deleteRelation(attrGroupRelationVos);

    return R.ok();
}

@Override
public void deleteRelation(@RequestBody AttrGroupRelationVo[] vos) {
//        relationDao.delete(new QueryWrapper<>().eq("attr_id", 1L)
//                .eq("attr_group_id", 1L))
    List<AttrAttrgroupRelationEntity> collect = Arrays.asList(vos).stream().map(item -> {
        AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
        BeanUtils.copyProperties(item, relationEntity);
        return relationEntity;
    }).collect(Collectors.toList());
    relationDao.deleteBatchRelation(collect);
}

void deleteBatchRelation(@Param("entities") List<AttrAttrgroupRelationEntity> entities);
<delete id="deleteBatchRelation">
    DELETE FROM `pms_attr_attrgroup_relation` WHERE
    <foreach collection="entities" item="item" separator="OR">
        (attr_id=#{item.attrId} AND attr_group_id=#{item.attrGroupId})
    foreach>
delete>

这里有个注意点 @RequestBody 不加会报错 找不到 vo 构造器

测试删除

后注:这里设计还是很巧妙的,传参方式是我未曾设想的

修查询关联的空指针bug

@Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {
        List<AttrAttrgroupRelationEntity> entities = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                .eq("attr_group_id", attrgroupId));

        List<Long> attrIds = entities.stream().map(attr -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());

        // 非空判断
        if (attrIds == null || attrIds.size() == 0) return null;

        List<AttrEntity> groupEntities = this.listByIds(attrIds);

        return groupEntities;
    }

获取属性分组没有关联的其他属性

谷粒商城-day12-平台属性_第19张图片 谷粒商城-day12-平台属性_第20张图片
/**
     * 获取属性分组没有关联的其他属性
     */
    @RequestMapping("/{attrgroupId}/noattr/relation")
    public R attrNoRelation(@RequestParam Map<String, Object> params,
                            @PathVariable("attrgroupId") Long attrgroupId
    ) {
        PageUtils page = attrService.getRelationAttr(params, attrgroupId);

        return R.ok().put("page", page);
    }

/**
     * 获取属性分组没有关联的其他属性
     *
     * @param params
     * @param attrgroupId
     * @return
     */
    @Override
    public PageUtils getRelationAttr(Map<String, Object> params, Long attrgroupId) {
        // 1. 当前分组只能关联自己所属分类里面的所有属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId();
        // 2.当前分组只能关联别的分组没有引用的属性
        // 2.1 当前分类下的其他分组
        List<AttrGroupEntity> groupEntities = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>()
                .eq("catelog_id", catelogId);

        List<Long> collect = groupEntities.stream().map(item -> {
            return item.getAttrGroupId();
        }).collect(Collectors.toList());

        // 2.2 这些分组关联的属性
        List<AttrAttrgroupRelationEntity> groupId = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                .in("attr_group_id", collect));
        List<Long> attrIds = groupId.stream().map(item -> {
            return item.getAttrId();
        }).collect(Collectors.toList());
        // 2.3从当前分类的所有属性中移除这些属性
        QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId)
                .eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE);

        if (attrIds != null && attrIds.size() > 0) {
            queryWrapper.notIn("attr_id", attrIds);
        }

        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            queryWrapper.and(w -> {
                w.eq("attr_id", key).or().like("attr_name", key);
            });
        }

        IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), queryWrapper);

        PageUtils pageUtils = new PageUtils(page);

        return pageUtils;
    }

测试谷粒商城-day12-平台属性_第21张图片

然后把4号属性关联到另外一个分组,看这里是否还能查得到

添加属性与分组关联关系

谷粒商城-day12-平台属性_第22张图片 谷粒商城-day12-平台属性_第23张图片
/**
     * 添加属性与分组关联关系
     */
    @PostMapping("/attr/relation")
    public R addRelation(@RequestBody List<AttrGroupRelationVo> vos) {

        relationService.saveBatch(vos);

        return R.ok();
    }

@Override
    public void saveBatch(List<AttrGroupRelationVo> vos) {
        List<AttrAttrgroupRelationEntity> collect = vos.stream().map(item -> {
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(item, relationEntity);
            return relationEntity;
        }).collect(Collectors.toList());
        this.saveBatch(collect);
    }

处理两个空指针

AttrServiceImpl 查询和保存的时候

谷粒商城-day12-平台属性_第24张图片 谷粒商城-day12-平台属性_第25张图片

小总结

这里讲的顺序其实理解起来还是有点小麻烦的,特别是对于规格参数和销售属性的理解,这两个其实是保存在一张表里面的,然后销售属性是没有分组信息的,在设置分组关联的时候需要做分支判断

你可能感兴趣的