前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >猿实战11——类目属性绑定之el-tree的使用

猿实战11——类目属性绑定之el-tree的使用

作者头像
山旮旯的胖子
发布2020-09-14 10:17:56
8620
发布2020-09-14 10:17:56
举报
文章被收录于专栏:猿人工厂

猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,变身猿人找到工作不是问题。想要一起实战吗?关注公号即可获取基础代码!

上一个章节,猿人君教会了你实现了后台类目的三级联动,今天我们继续来讲述,新增属性的实现。

功能概览

我们先看看新增属性的功能。

在页面选择类目后(目前暂时要求只新增1.2级类目属性),点击新增属性按钮,可以搜索属性库(要求同时检索属性以及属性组,同时支持模糊左匹配查询),通过勾选的方式新增属性为当前类目的属性。

属性展示之el-tree

我们可以很直观的看出,属性,是以分组的形式进行展示,当然,有的属性并没有从属于,某一个属性组,我们可以考虑一个叫“未分组”的属性组,用于归纳未分组的属性。

这样,属性组和属性之间,就形成了一种父子关系,对于这样的树形展示,element UI 提供了el-tree这样的组件,用于展现数据。

大家可以看一下官网上的内容。https://element.eleme.cn/#/zh-CN/component/tree

el-tree的属性和事件,相对来说比较丰富,就我们系统需要用到的而言,仅仅是展示,然后会关注数据的选择。

Data:用于展示的数据

Node-key:节点id的名称

default-expanded-keys:默认展开的节点的 key 的数组

props:定义数据节点的参数,详见上表

render-content:自定义,展示回调函数。

@check-change:节点选中状态发生变化时的回调。

属性检索后端实现

考虑到,属性和属性值的数据需要一起按照分组进行展示,我们需要定义一个专门用于显示的类来支撑,数据展示。像这样的类往往叫做VO。

由于是属性组内部再包装了,具体的属性,那么我们可以相对较快的定义这样的结构。

代码语言:javascript
复制
package com.pz.basic.mall.domain.product.property.vo;
 
import com.pz.basic.mall.domain.base.BaseDO;
import com.pz.basic.mall.domain.product.property.MallProperty;
 
import java.util.List;
 
public class MallGroupVo extends BaseDO {
 
    private Long id;
 
    private String label;
 
    private List<MallProperty> children;
 
   //省略getter setter
}
 
 
/**
 * Copyright(c) 2004-2020 pangzi
 * com.pz.basic.mall.domain.product.property.MallProperty.java
 */
package com.pz.basic.mall.domain.product.property;
 
import com.pz.basic.mall.domain.base.BaseDO;
 
import java.util.Date;
 
 
/**
 *
 * @author pangzi
 * @date 2020-06-28 11:40:14
 *
 */
public class MallProperty extends BaseDO {
 
    /**属性库属性ID**/
private Long propertyId;


    /**属性库属性名称**/
private String propertyName;


    /**属性分组ID,来自property_group表**/
private Long groupId;


    /**键值对,扩展字段**/
private String features;


    /**排序**/
private Integer sortOrder;


    /**状态
0=停用
1=启用
**/
private Integer status;


    /**创建人**/
private String createUser;


    /**修改人**/
private String modifyUser;


    /**创建时间**/
private Date created;


    /**最后修改时间**/
private Date modified;

}

接下来要做的事情,自然是要返回数据了。在MallCategoryPropertyController中定义方法,返回属性组俩表数据

代码语言:javascript
复制
/**
     * 返回类目属性列表
     * @param queryMallProperty
     * @return
     */
    @RequestMapping("/findForSelect")
    public  Result<List<MallGroupVo>> findForSelect(@RequestBody QueryMallProperty queryMallProperty){
        return mallCategoryPropertyService.getMallPropertyGroup(queryMallProperty);
    }

我们可以思考下服务层的实现,由于我们的属性表中,只有属性组ID,而没有属性组名称,而我们的检索条件是需要同时支持属性组名称和属性名称进行查询的,这该如何是好?

一般来讲,很常见而且有些偏传统管理软件的实现方式是直接将属性表与属性组表进行关联查询。但是互联网行业在做查询时,考虑到sql的后续优化,是需要控制表之间的关联连接查询的。通常情况下,需要做将这种join关系做些转化。比如将join转化为in的方式,就是最常见的一种方式。

比如我们可以先查询出符合条件的属性组的id,然后再将这些以in的方式在属性表中做查询就好了。

代码语言:javascript
复制
public Result<List<MallGroupVo>> getMallPropertyGroup(QueryMallProperty queryMallProperty) {
 
Result<List<MallGroupVo>> result = new Result<List<MallGroupVo>>();
 
QueryMallPropertyGroup groupQuery = new QueryMallPropertyGroup();
groupQuery.setGroupNameLike(queryMallProperty.getPropertyNameLike());

//根据分组名查询分组对象,用于后续展示分组名,以及对属性表支持对应的分组id 用于属性表的 or 关系查询

代码语言:javascript
复制
List<MallPropertyGroup>  groupList  =getGroupList(groupQuery);
 
if(!CollectionUtils.isEmpty(groupList)){
List<Long> idList = groupList.stream().map(e -> e.getGroupId()).collect(Collectors.toList());
queryMallProperty.setGroupIdList(idList);
}
 
List<MallProperty> propertyList=mallPropertyDao.selectMallPropertyByQuery(queryMallProperty);
 
List<Long> shieldIdList=getShieldPropertyIdList(queryMallProperty);
 
//删除需要屏蔽的对象
if(!CollectionUtils.isEmpty(shieldIdList)){
propertyList.removeIf(a -> {
return shieldIdList.stream().anyMatch(b -> {
if (b!= null && b.equals(a.getPropertyId())) {
return true;
} else {
return false;
}
});
});
}
List<MallGroupVo> dataList=getMallGroupVoList(propertyList,groupList);
result.addDefaultModel(dataList);
return result;
}
 
代码语言:javascript
复制
private List<MallGroupVo> getMallGroupVoList(List<MallProperty> propertyList,List<MallPropertyGroup> groupList ){
Map<Long,MallGroupVo> groupMap = new HashMap<Long,MallGroupVo>();
 
List<MallGroupVo> dataList= new ArrayList<MallGroupVo>();
MallGroupVo group =null;
 
MallPropertyGroup mallGroup=null;
 
if(!CollectionUtils.isEmpty(propertyList)){
 
for(MallProperty property:propertyList){
 
mallGroup=getMallPropertyGroup(groupList,property.getGroupId());
 
if(null==mallGroup){
group=groupMap.get(UnsignedGroupId);
 
}else{
group=groupMap.get(property.getGroupId());
}
if(null==group){
List<MallGroupVo> list = new ArrayList<MallGroupVo>();
List<MallProperty> dbList = new  ArrayList<MallProperty>();
dbList.add(property);
group = new MallGroupVo();
list.add(group);
if(null==mallGroup){
group.setId(UnsignedGroupId);
group.setLabel(UnsignedGroupName);
}else{
group.setId(mallGroup.getGroupId());
group.setLabel(mallGroup.getGroupName());
}
group.setChildren(dbList);
groupMap.put(group.getId(),group);
}else{
group.getChildren().add(property);
}
}
 
}
if(!CollectionUtils.isEmpty(groupMap) ){
dataList.addAll(groupMap.values());
}
return dataList;
}
代码语言:javascript
复制
/**
 * 获取需要屏蔽的对象
 * @param queryMallProperty
 * @return
 */
private List<Long> getShieldPropertyIdList(QueryMallProperty queryMallProperty){
 
List<Long> catIdList = new ArrayList<Long>();
 
if(null!=queryMallProperty.getCatOneId()){
catIdList.add(queryMallProperty.getCatOneId());
}
 
if(null!=queryMallProperty.getCatTwoId()){
catIdList.add(queryMallProperty.getCatTwoId());
}
 
if(null!=queryMallProperty.getCatThreeId()){
catIdList.add(queryMallProperty.getCatThreeId());
}
 
if(!CollectionUtils.isEmpty(catIdList)){
QueryMallCategoryProperty query = new QueryMallCategoryProperty();
    query.setCategoryIdList(catIdList);
List<MallCategoryProperty> dataList=mallCategoryPropertyDao.selectMallCategoryPropertyByQuery(query);
List<Long> shieldIdList = dataList.stream().map(e -> e.getPropertyId()).collect(Collectors.toList());
return shieldIdList;
}
 
return null;
 
}

如何使用List的方面的in语句?这里可以给你看一下

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 猿人工厂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档