SPU: Standard Product Unit(标准化产品单元)
是商品信息聚合的最小单位, 是一组可复用、 易检索的标准化信息的集合, 该集合描述了一个产品的特性。
- iphoneX 是 SPU、 MI 8 是 SPU
- iphoneX 64G 黑曜石 是 SKU
- MI8 8+64G+黑色 是 SKU
2.基本属性【 规格参数】 与销售属性SKU: Stock Keeping Unit(库存量单位)
即库存进出计量的基本单元, 可以是以件, 盒, 托盘等为单位。 SKU 这是对于大型连锁超市DC(配送中心) 物流管理的一个必要的方法。 现在已经被引申为产品统一编号的简称, 每种产品均对应有唯一的 SKU 号。
每个分类下的商品共享规格参数, 与销售属性。 只是有些商品不一定要用这个分类下全部的属性;
- 属性是以三级分类组织起来的
- 规格参数中有些是可以提供检索的
- 规格参数也是基本属性, 他们具有自己的分组
- 属性的分组也是以三级分类组织起来的
- 属性名确定的, 但是值是每一个 商品不同来决定的
执行sys_menus.sql或gulimall_admin.sql
数据库
前端
4.属性分组模块 attrgroup.vue新建文件attrgroup.vue src/views/modules/product/attrgroup.vue
布局
5.前端分类列表组件抽取 category.vue分类列表 表单 //@import url(); 引入公共 css 类
因为分类列表在其他地方也会使用到,所以单独抽取出来封装成组件
新建一个category.vue 位置:src/views/modules/common/category.vue
1.完整示例
2.列表不显示问题
发送请求成功,也获取到数据了,但是列表不显示
解决
el-tree的props
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| label | 指定节点标签为节点对象的某个属性值 | string, function(data, node) | — | — |
| children | 指定子树为节点对象的某个属性值 | string | — | — |
| disabled | 指定节点选择框是否禁用为节点对象的某个属性值 | boolean, function(data, node) | — | — |
| isLeaf | 指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效 | boolean, function(data, node) | — | — |
通过设置props的label与children属性来解决
3.输入关键字进行过滤解决效果
4.子组件向父节点传值(利用事件)filter-node-method:对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏
返回值:Function(value, data, node)
value:筛选的值
data:筛选的数据
node:筛选的节点
1.子传值node-click:节点被点击时的回调
回调函数:共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。
//tree-node-click随便取值,只要在父组件取名相同
//后面参数为传的值
this.$emit("tree-node-click", data, node, component);
2.父取值
6.将抽取的组件注册到attrgroup 1.导入
import Category from "../common/category";2.组件注册
components: {
Category
},
3.使用
4.此部分代码
4.效果 7.新增表单表单 //@import url(); 引入公共 css 类
查询
查询全部
新增
批量删除
关联
修改
删除
1.attr-group-relation.vue
src/views/modules/product/attr-group-relation.vue 修改关联关系
查询
取 消
确认新增
新建关联
批量删除
{{i}}
{{scope.row.valueSelect.split(";")[0]+" ..."}}
移除
2.attrgroup-add-or-update.vue
src/views/modules/product/attrgroup-add-or-update.vue 新增/修改模态框
1.级联选择器 (父传子)取消 确定
为所属分类字段新增级联选择器
组件定义 src/views/modules/common/category-cascader.vue
使用 src/views/modules/product/attrgroup-add-or-update.vue
遇到的问题
原因
三级子分类中没有子节点了导致数组为空
解决
让没有子节点的分类,不传children字段
修改gulimall-product/src/main/java/site/zhourui/gulimall/product/entity/CategoryEntity.java
//为空就不传值 @JsonInclude(JsonInclude.Include.NON_EMPTY) //此字段在数据库表中不存在 @TableField(exist=false) private Listchildren;
2.级联回显效果
但现在所属分类id,只有三级分类的id
想要在编辑时回显级联分类,就必须新增后端接口,根据三级分类id查询分类路径id数组
新增根据三级分类id查询分类路径id数组
为gulimall-product/src/main/java/site/zhourui/gulimall/product/entity/AttrGroupEntity.java新增字段
@TableField(exist = false) private Long[] catelogPath;
gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/CategoryServiceImpl.java
新增接口
Long[] findCatelogPath(Long catelogId);
gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/AttrGroupServiceImpl.java
新增接口实现
//[2,25,225]
@Override
public Long[] findCatelogPath(Long catelogId) {
List paths = new ArrayList<>();
List parentPath = findParentPath(catelogId, paths);
//反序操作
Collections.reverse(parentPath);
return parentPath.toArray(new Long[parentPath.size()]);
}
//225,25,2
//根据catelogId查询出目录路径数组,此时是逆序的 (递归操作)
private List findParentPath(Long catelogId,List paths){
//1、收集当前节点id
paths.add(catelogId);
CategoryEntity byId = this.getById(catelogId);
//找到根节点才会停止
if(byId.getParentCid()!=0){
findParentPath(byId.getParentCid(),paths);
}
return paths;
}
修改gulimall-product/src/main/java/site/zhourui/gulimall/product/controller/AttrGroupController.java info方法
@Autowired
private CategoryService categoryService;
@RequestMapping("/info/{attrGroupId}")
//@RequiresPermissions("product:attrgroup:info")
public R info(@PathVariable("attrGroupId") Long attrGroupId){
AttrGroupEntity attrGroup = attrGroupService.getById(attrGroupId);
Long catelogId = attrGroup.getCatelogId();
Long[] path = categoryService.findCatelogPath(catelogId);
attrGroup.setCatelogPath(path);
return R.ok().put("attrGroup", attrGroup);
}
8.新增后端接口级联回显效果
gulimall-product/src/main/java/site/zhourui/gulimall/product/service/AttrGroupService.java
新增接口
PageUtils queryPage(Map params, Long catelogId);
gulimall-product/src/main/java/site/zhourui/gulimall/product/service/impl/AttrGroupServiceImpl.java
新增接口实现
@Override
public PageUtils queryPage(Map 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 wrapper = new QueryWrapper();
if(!StringUtils.isEmpty(key)){
wrapper.and((obj)->{
obj.eq("attr_group_id",key).or().like("attr_group_name",key);
});
}
if( catelogId == 0){
IPage page = this.page(new Query().getPage(params),
wrapper);
return new PageUtils(page);
}else {
wrapper.eq("catelog_id",catelogId);
IPage page = this.page(new Query().getPage(params),
wrapper);
return new PageUtils(page);
}
}
gulimall-product/src/main/java/site/zhourui/gulimall/product/controller/AttrGroupController.java
修改list接口
@RequestMapping("/list/{catelogId}")
//@RequiresPermissions("product:attrgroup:list")
public R list(@RequestParam Map params,
@PathVariable("catelogId") Long catelogId){
// PageUtils page = attrGroupService.queryPage(params);
PageUtils page = attrGroupService.queryPage(params,catelogId);
return R.ok().put("page", page);
}
测试http://localhost:88/api/product/attrgroup/list/0?t=1633946911824&page=1&limit=10&key=
结果
前端调用结果:



