文章目录
- 7.1 平台属性-规格参数
- 7.11 新增规格参数
- 7.12 查询分类规格参数列表
- 7.13 查询属性详情
- 7.14 修改规格参数
- 7.2 平台属性-销售属性
- 7.3 属性分组关联
- 7.31 属性分组关联属性
- 7.32 移除属性与分组的关联关系
- 7.33 查询属性分组未关联的所有属性
- 7.34 添加属性与分组关联关系(点击确认新增)
平台属性用到三张表
① 进入平台属性—》规格参数—》新增
数据库保存的数据,就是新增的属性数据:(pms_attr属性表)
② 进入平台属性—》属性分组—》关联:
属性分组表如下:
③点击关联,增加后保存的数据是在关联表如下:属性分组与属性的关联表。
7.1 平台属性-规格参数
7.11 新增规格参数
① 在com.atguigu.gulimall.product.vo包下新建一个AttrVo对象,用于接收页面提交的请求数据,这个AttrVo对象就是比AttrEntity实体类多了一个字段attrGroupId,并且该字段不在数据库中:
AttrVo
@Data
public class AttrVo {
/**
* 属性id
*/
private Long attrId;
/**
* 属性名
*/
private String attrName;
/**
* 是否需要检索[0-不需要,1-需要]
*/
private Integer searchType;
/**
* 值类型[0-为单个值,1-可以选择多个值]
*/
private Integer valueType;
/**
* 属性图标
*/
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;
}
② 在AttrController中修改新增属性的方法:
@RequestMapping("/save")
public R save(@RequestBody AttrVo attr){
attrService.saveAttr(attr);
return R.ok();
}
③ 在attr表中保存基本属性信息,然后在关联表中保存关联信息,在AttrServiceImpl类中:
@Autowired
private AttrAttrgroupRelationDao relationDao;
@Transactional
@Override
public void saveAttr(AttrVo attr) {//这个attr是前端页面传过来的数据,与VO数据:AttrVo对应
AttrEntity attrEntity = new AttrEntity();
BeanUtils.copyProperties(attr,attrEntity);//将attr的数据(AttrVo对应)复制到attrEntity实体类中的数据
//保存基本数据
this.save(attrEntity);
//保存关联数据
AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
//将以下的AttrGroupId(属性分组id)、AttrId(属性id)设置到属性与属性分组关联表中
relationEntity.setAttrGroupId(attr.getAttrGroupId());
relationEntity.setAttrId(attrEntity.getAttrId());
relationDao.insert(relationEntity);//保存进数据库
}
④ 测试:新增属性
对应的relation关联表(属性id1和2都对应着属性分组1)
7.12 查询分类规格参数列表
前端API:https://easydoc.xyz/s/78237135/ZUqEdvA4/Ld1Vfkcd
① 请求路径:/product/attr/base/list/{catelogId},分页查询,模糊查询
② 在AttrController中:
@RequestMapping("/base/list/{catelogId}")
public R list(@RequestParam Map<String, Object> params,
@PathVariable("catelogId") Long catelogId){
PageUtils page = attrService.queryBaseAttrPage(params,catelogId);
return R.ok().put("page",page);
}
③ 在AttrServiceImpl类中:
@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=key 或者 attr_name like %key%
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);
}
重启项目,查看规格参数,可以看到在响应数据时还需要响应所属分类和所属分组(缺少),可以参考API前端文档。
④在vo包下创建 响应对象AttrRespVo,比AttrEntity多了所属分类和所属分组:
@Data
public class AttrRespVo extends AttrVo {
/**
* "catelogName": "手机/数码/手机", //所属分类名字
* "groupName": "主体", //所属分组名字
*/
private String catelogName;
private String groupName;
}
⑤ 在AttrServiceImpl类中修改queryBaseAttrPage()方法:
@Resource
private AttrGroupDao attrGroupDao;
@Resource
private CategoryDao categoryDao;
@Override
public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId) {
QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>();
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);
//查询一条记录
AttrAttrgroupRelationEntity attrId = relationDao.selectOne(
new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
//根据attrId查询出AttrGroupEntity,然后查询出AttrGroupName
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;
}
再次测试,发现已经加上了所属分类和所属分组
7.13 查询属性详情
需求:在修改规格参数时,希望回显所属分类(分类的完整路径)和所属分组
前端接口API:https://easydoc.xyz/s/78237135/ZUqEdvA4/7C3tMIuF如下:
① AttrRespVo中编写需要响应的字段:
@Data
public class AttrRespVo extends AttrVo {
private String catelogName;
private String groupName;
private Long[] catelogPath;//这里添加分类完整路径
}
② 在AttrController中修改info()方法,加上响应字段:
@RequestMapping("/info/{attrId}")
public R info(@PathVariable("attrId") Long attrId){
// AttrEntity attr = attrService.getById(attrId);,原先这个AttrEntity返回消息太少
//返回响应AttrRespVo,这个自定义的实体类,返回的消息多
AttrRespVo respVo = attrService.getAttrInfo(attrId);
return R.ok().put("attr", respVo);
}
③ 在AttrServiceImpl类中:
@Override
public AttrRespVo getAttrInfo(Long attrId) {
AttrRespVo respVo = new AttrRespVo();
AttrEntity attrEntity = this.getById(attrId);
//将attrEntity中的基本属性拷贝到respVo
BeanUtils.copyProperties(attrEntity,respVo);
//1、设置分组信息
//查询一条记录,条件为:attr_id=attrId,前端传过来的数据属性id:attrId,通过它查询属性与属性分组关联表(pms_attr_attrgroup_relation)的信息
AttrAttrgroupRelationEntity attrgroupRelation = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
if(attrgroupRelation!=null){
//设置attr_group_id和attr_groupname字段
respVo.setAttrGroupId(attrgroupRelation.getAttrGroupId());
//attrGroupEntity分组表
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupRelation.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;
}
测试:点击修改,可以显示所属分类和所属分组,但是当修改所属分组后,保存不成功,因为我们只做了新增的功能save(),并没有完成修改保存的功能,即修改update()方法:
7.14 修改规格参数
① 在AttrController中:修改update方法
@RequestMapping("/update")
public R update(@RequestBody AttrVo attr){
attrService.updateAttr(attr);
return R.ok();
}
② 在AttrServiceImpl类中:
@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 UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attr.getAttrId()));
}else{
relationDao.insert(relationEntity);
}
7.2 平台属性-销售属性
销售属性与规格参数不一样,它不需要和属性分组关联。所以需要做一些attr_type(属性类别)的判断。
① 前端API接口文档:https://easydoc.xyz/s/78237135/ZUqEdvA4/FTx6LRbR
② 数据库分析:对于pms_attr这张表,既存放了规格参数(基本属性),又存放了销售属性,当attr_type=0时代表销售属性,当attr_type=1时代表规格参数:
③在gulimall-common创建一个attr_type(属性分类判断)
attr_type=1:规格参数(基本属性);attr_type=0:销售属性
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;
}
}
}
④修改AttrServiceImpl的一些方法,只有当attr_type=1:规格参数(基本属性)时,才会进行保存,修改,所以需要加判断
//-----saveAttr:属性保存时代码
@Transactional
@Override
public void saveAttr(AttrVo attr) {
AttrEntity attrEntity = new AttrEntity();
// attrEntity.setAttrName(attr.getAttrName());
BeanUtils.copyProperties(attr,attrEntity);
//1、保存基本数据
this.save(attrEntity);
//2、保存关联关系,只有attr_type=1:规格参数(基本属性)时
if(attr.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && attr.getAttrGroupId()!=null){
AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
relationEntity.setAttrGroupId(attr.getAttrGroupId());
relationEntity.setAttrId(attrEntity.getAttrId());
relationDao.insert(relationEntity);
}
}
//--------------queryBaseAttrPage 查询属性,添加type属性判断
@Override
public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {
//此处模糊查询,不用判断,规格参数和销售属性 都需要模糊查询
QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().eq("attr_type","base".equalsIgnoreCase(type)?ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode():ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
//.............省略
//1、设置分类和分组的名字
if("base".equalsIgnoreCase(type)){//判断
AttrAttrgroupRelationEntity attrId = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
//前面有代码,此处省略.........
}
//--------------------getAttrInfo:属性详情
@Override
public AttrRespVo getAttrInfo(Long attrId) {
AttrRespVo respVo = new AttrRespVo();
AttrEntity attrEntity = this.getById(attrId);
BeanUtils.copyProperties(attrEntity,respVo);
//判断是否是基本属性
if(attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
//1、设置分组信息
AttrAttrgroupRelationEntity attrgroupRelation = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
//.....................省略
}
//------------------updateAttr:更新属性
@Transactional
@Override
public void updateAttr(AttrVo attr) {
AttrEntity attrEntity = new AttrEntity();
BeanUtils.copyProperties(attr,attrEntity);
this.updateById(attrEntity);
//判断是否是基本属性,是就执行
if(attrEntity.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
//1、修改分组关联
AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
//...........省略
⑤AttrController的修改
//product/attr/sale/list/0?
///product/attr/base/list/{catelogId}
@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);
}
⑥测试:
销售属性都不关联属性分组
7.3 属性分组关联
7.31 属性分组关联属性
① 获取指定属性分组关联的所有属性:获取属性分组的关联的所有属性
接口文档:https://easydoc.xyz/s/78237135/ZUqEdvA4/LnjzZHPj
②在AttrGroupController中,根据attrgroupId找到组内关联的所有属性:
@RequestMapping("/{attrgroupId}/attr/relation")
public R attrRelation(@PathVariable("attrgroupId") Long attrgroupId){
List<AttrEntity> entities = attrService.getRelationAttr(attrgroupId);
return R.ok().put("data",entities);
}
③AttrServiceImpl添加以下方法
/* *
* 根据分组id查找关联的所有基本属性
* @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());
if(attrIds == null || attrIds.size() == 0){
return null;
}
Collection<AttrEntity> attrEntities = this.listByIds(attrIds);
return (List<AttrEntity>) attrEntities;
}
7.32 移除属性与分组的关联关系
接口文档:https://easydoc.xyz/s/78237135/ZUqEdvA4/qn7A2Fht
属性并不删除,只是移除属性和分组之间的关联关系而已,
①在AttrGroupController中:
//请求参数:[{"attrId":1,"attrGroupId":2}]
@PostMapping("/attr/relation/delete")
public R deleteRelation( @RequestBody AttrGroupRelationVo[] vos){
attrService.deleteRelation(vos);
return R.ok();
}
②在vo包下自定义AttrGroupRelationVo
@Data
public class AttrGroupRelationVo {
private Long attrId;
private Long attrGroupId;
}
③在AttrServiceImpl中:
@Override
public void deleteRelation(AttrGroupRelationVo[] vos) {
List<AttrAttrgroupRelationEntity> entities = Arrays.asList(vos).stream().map((item) -> {
AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
BeanUtils.copyProperties(item, relationEntity);
return relationEntity;
}).collect(Collectors.toList());
//批量移除属性分组和属性的关联关系
relationDao.deleteBatchRelation(entities);
}
④下面要做的就是自己手动的写sql语句,实现deleteBatchRelation(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>
⑤当执行测试时,点移除,发现pms_attr_attrgroup_relation表的关联数据被删除,
但是pms_attr的属性并没有删除(因为没有点规格参数或销售属性栏的删除按钮)
7.33 查询属性分组未关联的所有属性
需求分析:点击关联后,新建关联,获取属性分组里面还没有关联的本分类里面的其他基本属性(规格参数),方便添加新的关联
前端接口文档:https://easydoc.xyz/s/78237135/ZUqEdvA4/d3EezLdO
在AttrGroupController中:
//获取当前分组没有关联的所有属性
@RequestMapping("/{attrgroupId}/noattr/relation")
public R attrNoRelation(@PathVariable("attrgroupId") Long attrgroupId,
@RequestParam Map<String,Object> params){
PageUtils page = attrService.getNoRelationAttr(params,attrgroupId);
return R.ok().put("page",page);
}
在AttrServiceImpl中:
@Override
public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {
//1、当前分组只能关联自己所属的分类里面的所有属性
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
Long catelogId = attrGroupEntity.getCatelogId();
//2、当前分组只能关联别的分组没有引用的属性
//2.1)、当前分类下的所有分组
List<AttrGroupEntity> group = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
//获取所有分组的group_id集合
List<Long> collect = group.stream().map(item -> {
return item.getAttrGroupId();
}).collect(Collectors.toList());
//2.2)、这些分组关联的属性,groupId是属性集合
List<AttrAttrgroupRelationEntity> groupId = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", collect));
//获取属性id集合(attr_id)
List<Long> attrIds = groupId.stream().map(item -> {
return item.getAttrId();
}).collect(Collectors.toList());
//2.3)、从当前分类的所有属性中移除这些属性;
QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).eq("attr_type",ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
if(attrIds!=null && attrIds.size()>0){
wrapper.notIn("attr_id", attrIds);
}
String key = (String) params.get("key");
if(!StringUtils.isEmpty(key)){
wrapper.and((w)->{
w.eq("attr_id",key).or().like("attr_name",key);
});
}
IPage<AttrEntity> page = this.page(new Query<AttrEntity>().getPage(params), wrapper);
PageUtils pageUtils = new PageUtils(page);
return pageUtils;
}
7.34 添加属性与分组关联关系(点击确认新增)
前端接口:https://easydoc.xyz/s/78237135/ZUqEdvA4/VhgnaedC
AttrGroupController
@RequestMapping("/attr/relation")
public R addRelation(@RequestBody List<AttrGroupRelationVo> vos){
relationService.saveBatch(vos);
return R.ok();
}
AttrAttrgroupRelationServiceImpl
@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);
}