@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);
}
}
测试
查询所有现在也可以用模糊查询
添加一个 attr-group-relation 组件
这里放在后面实现,我们先来处理规格参数和销售属性
属性这里新增时缺少分组信息的关联写入,重写save
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;
}
/**
* 保存
*/
@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);
}
0 是查询所有
带模糊查询功能
这个功能其实和之前的实现是类似的
// /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);
}
返回加上 所属分类和所属分组
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;
}
先来修改查询详情功能,目前没有回显,缺少 catelogPath 属性
修改 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 来区分
这里重写查询,把对 规格参数的查询和销售属性的查询合并到一起
// /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 表中创建记录
/**
* 获取属性分组的关联的所有属性
*/
@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;
}
测试
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 构造器
测试删除
后注:这里设计还是很巧妙的,传参方式是我未曾设想的
@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;
}
/**
* 获取属性分组没有关联的其他属性
*/
@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;
}
然后把4号属性关联到另外一个分组,看这里是否还能查得到
/**
* 添加属性与分组关联关系
*/
@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 查询和保存的时候
这里讲的顺序其实理解起来还是有点小麻烦的,特别是对于规格参数和销售属性的理解,这两个其实是保存在一张表里面的,然后销售属性是没有分组信息的,在设置分组关联的时候需要做分支判断