目录
什么是SPU?
什么是SKU?
规格参数
销售属性
三级分类-属性组-属性的关联关系
SPU-属性&SKU-属性的关联关系
预期效果:
属性分组之前端组件抽取&父子组件交互
获取分类的属性组
分组新增和级联选择器
分组修改&级联显示器回显
品牌分类关联与级联更新
Standard Product Unit(标准化产品单元):是商品信息聚合的最小单位,是一组可复用、易检索的标注化信息的集合,该集合描述了一个产品的特征
例如:Apple iPhone 13 就是一个SPU
存放SPU的表结构:pms_spu_info
Stock Keeping Unit(库存量单位),即库存进出计量的基本单位,可以是件,盒,托盘等为单位。现在已经被引申为产品统一编号的简称,每种产品均对应有唯一的SKU号
例如:Apple iPhone 13 粉色 256G 可以确定商品的价格和库存的集合我们称为SPU
存放SKU的表结构:pms_sku_info
例如:手机分类下的产品都会有一个规格与包装属性,也就是我们常说的规格参数
规格参数由属性组和属性组成
左侧第一栏即属性组,中间一栏即属性,右侧一栏即属性的值
属性组的数据库中表的结构:pms_attr_group
通过catlog_id来关联属于那个商品分类
属性的数据库中表的结构:pms_attr
关联属性组和属性的数据库中表结构: pms_attr_attrgroup_relation
以下括起来的都是销售属性
每个分类下的商品共享规格参数和销售属性,只是有些商品不一定要用这个分类下全部的属性。
说明:
1.属性是以三级分类组织起来的
2.规格参数中有些是可以提供检索的
3.规格参数也是基本属性,他们具有自己的分组
4.属性的分组也是由三级分类组织起来的
5.属性名确定的,但是值每一个商品不同来决定的
1.创建属性分组菜单
由于之前创建过,所以这里不再一一创建菜单,将sys_menus.sql在gulimall_admin数据库中创建
新增菜单
接口文档地址:1、分页请求参数 - 谷粒商城
2.在product文件夹下创建attrgroup.vue
我们想要的效果是左边是三级分类显示,右边是属性组显示 。因此,我们需要使用布局组件
3.使用布局组件实现左右布局
gutter属性:用于设置每列之间的间隙
说明:每一行最多有24列
将三级分类菜单设置为6列,将表格设置为18列
不仅仅属性组管理需要用到三级分类菜单,还有规格参数、销售属性等都要用到。因此,将三级分类菜单抽取成一个组件
4.将三级分类抽取成公用组件
①在modules下创建common文件夹并且创建三级分类公用组件category.vue
② 抽取组件
5.编写属性组表格
将逆向工程生成的attrgroups.vue复制到el-col中
发现需要导入attrgroup-add-or-update组件,将逆向工程生成的组件导入
我们想要点击叶子结点,表格就能显示关联叶子结点的属性组。这个功能要怎么实现呢?
通过使用父子组件来实现此功能,父子组件通过事件进行交互,事件会携带数据
这里子组件就是common下的category.vue,父组件就是attrgroups.vue
父子组件交互的步骤:
①为子组件绑定事件
②使用this.$emit("事件名",data...)向父组件传递事件和数据,事件名:自定义(默认使用-分割)
data...:传递的数据不限个数
查看事件传递的数据
1.查看接口文档
请求类型和请求路径:
请求体:
响应体:
2. 编写接口文档
工具类的讲解:
①Query类中的getPage方法会将分页参数封装成IPage对象
②QueryWrapper类用于封装查询条件
③IPage的page方法会将分页查询条件和查询条件作为参数进行查询
④PageUtils会将IPage查询的结果进行一个封装
接口编写思路:
①判断catelogId为0还是其他值,为0则查询所有,为其他值则精确查询
②判断分页查询中的key是否为空,不为空则需要进行一个分类查询,可能通过id查询,也可能通过name模糊查询
public PageUtils queryAttrGroups(Map params, Long catelogId) {
QueryWrapper wrapper=null;
// 1.首先判断catelogId为0还是其他值,为0则查询所有,其他值则准确查询
if (catelogId == 0){
IPage page = this.page(
new Query().getPage(params),
new QueryWrapper()
);
return new PageUtils(page);
}else {
// 2.判断key是否有值
String key= (String) params.get("key");
if (StringUtils.isNotEmpty(key)){ // 使用StringUtils工具类中方法对key进行非空判断
// select * from pms_attr_group where catelog_id = ? and (attr_group_id =? or attr_group_name like %?%)
wrapper=new QueryWrapper().eq("catelog_id",catelogId)
.and((obj)->{
obj.eq("attr_group_id",key).or((item)->{item.like("attr_group_name",key);});
});
}else {
wrapper=new QueryWrapper().eq("catelog_id",catelogId);
}
IPage page = this.page(
new Query().getPage(params),
wrapper
);
return new PageUtils(page);
}
}
说明:
①QueryWrapper中的or或者and方法参数可以是函数式接口也就意味着可以使用lambda表达式作为接口的实例
②like:左右%,likeLeft:左%,likeRight:右%
3.前后联调
①编写一个获取属性组的方法
catId是我们动态获取,默认值为0,因此,我们要使用一对``(飘号)和${}来获取catId
②获取catId
设置catId的默认值
只有叶子节点才能获取到它的catId并且查询它的属性组,并且需要宠幸获取数据
③ 组件创建完成就要触发getDataList函数
当我们点击新增的时候,所属分类应该是一个级联选择器,而不是我们手动写一个catelogId
①使用级联选择器
绑定的change事件暂时用不到先删除,动态绑定选中的类目id
categories:用于存放的需要渲染的数据
categories是要从后台动态获取的,因此,复用获取数据的函数
组件创建后就要去获取数据
级联选择器的核心代码
v-model:绑定的是选择的路径
options:绑定查出的数据
props:自动插入数据
查看以下渲染效果:
出现原因:未将数组的属性值封装进props的属性值
解决方案:封装props的属性值
将data中的catId、name、children与props中的属性value、label、children一一绑定
查看效果
出现问题: 手机后面还有选择框
出现原因:手机的children是一个空数组,级联选择器会对空数组进行一个渲染
解决方案:让如果children属性为空的话后台,让后台不发送到前端
通过使用JsonInclude注解
value常用值:
Include.ALWAYS:默认策略,始终包含此属性,写了和没写一样
Include.NON_NULL:不为空时包含此属性
Include.NON_EMPTY:不为空、空字符串、空容器等情况时包含此属性
解决方案:将catlogId改为数组
说明: catelogId存放的是个数组,我们可以查看以下
可以看出将被选中的结点的catId,及其父结点的catId,以及父节点的父节点的catId封装进来了catelogId中 ,而我们只要选中结点的catId即数组最后一个元素
catelogIds:封装节点catId数组
catelogId:用于封装修改回显属性组的catelogId,默认为0
提交catId数组中的最后一个元素
出现问题:点击修改所选分类没有回显
分析:
①点击修改,调用addOrUpdateHandle
1.将addOrUpdateVisible设置为true,即启用对话框
2.this.$nextTick等对话框渲染完成之后去调用当前vue实例中导入的addOrUpdate组件的init方法
要想对话框所属分类回显,就得从后台获取到对应的路径
为了见名知意,将所有的catelogIds替换成catelogPath
后台代码编写:
①设置catelogPath属性
②注入CategoryService,要使用那张表就注入对应的service
代码完善:
效果:
解决方案:使用dialog的closed事件,当对话关闭时将回显路径置空
级联显示器优化: 一个个找太麻烦了,要有搜索功能
解决方案:使用级联选择器中的可搜索功能
出现问题:分页的总条数统计不正确
出现原因:mybatis-plus中要使用分页,需要配置分页插件
解决方案:配置mybatis-plus分页插件
完成品牌关联分类功能
一个品牌可以有多个分类,一个分类下有多个品牌,这是多对多的关系。因此,在数据库中表的设计,多对多关系需要设计一张中间表来关联两张表
1.设计一个关联分类按钮
2. 编写点击关联分类触发的对话框
3.点击关联关系触发函数的编写
点击取消或者确定将数据置为默认值
4. 编写新增关联功能,使用级联选择器
级联选择器中数据是点击新增关联按钮从后台获取的
向后台发送请求获取关联数据
后台代码编写
获取当前品牌关联的分类
新增当前品牌的关联的分类
出现问题:此次新增完之后,下次新增还保留着上次新增的categoryPath
解决方案:使用dialog的事件,当关闭对话框时将categoryPath置为空
关联表中的名称是属于冗余字段,当我们原始表中数据修改对应的关联表中冗余字段也要跟着修改
①当pms_category的categoryName修改时,pms_category_brand_relation中categoryName也要修改
测试
② 当pms_brand中的brandName修改时,pms_category_brand_relation中brandName也要做相应的修改
品牌功能搜索完善
功能完善,添加移除品牌关联分类功能
解决方案:使用表格的自定义模板即template