销售属性维护
base和sale公用一个方法
在相应的业务逻辑中添加一个类型值得判断,1是base,0是sale
在queryBaseAttrPage方法中添加一个分组判断,否则添加销售属性会空指针异常
效果【需要自己新增颜色销售属性】
点击修改,多添加一个蓝色可选值
由于销售属性和基本属性公用同一个保存和修改方法,所以中间表存入值时需要先判断,如果是销售属性就不需要分组,否则中间表的分组属性值为空。
由于经常使用到类型属性值提取一个常量属性,这样在维护的时候只需要更改枚举的值,不需要再动代码内部
完整代码
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完整代码
package com.example.gulimall.product.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.common.constant.ProductConstant;
import com.example.gulimall.product.dao.AttrAttrgroupRelationDao;
import com.example.gulimall.product.dao.AttrGroupDao;
import com.example.gulimall.product.dao.CategoryDao;
import com.example.gulimall.product.entity.AttrAttrgroupRelationEntity;
import com.example.gulimall.product.entity.AttrGroupEntity;
import com.example.gulimall.product.entity.CategoryEntity;
import com.example.gulimall.product.service.CategoryService;
import com.example.gulimall.product.vo.AttrRespVo;
import com.example.gulimall.product.vo.AttrVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.utils.PageUtils;
import com.example.common.utils.Query;
import com.example.gulimall.product.dao.AttrDao;
import com.example.gulimall.product.entity.AttrEntity;
import com.example.gulimall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
@Autowired
AttrAttrgroupRelationDao relationDao;
@Autowired
AttrGroupDao attrGroupDao;
@Autowired
CategoryDao categoryDao;
@Autowired
CategoryService categoryService;
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<AttrEntity> page = this.page(
new Query<AttrEntity>().getPage(params),
new QueryWrapper<AttrEntity>()
);
return new PageUtils(page);
}
@Transactional
@Override
public void saveAttr(AttrVo attr) {
final AttrEntity attrEntity = new AttrEntity();
BeanUtils.copyProperties(attr,attrEntity);
//首先保存新数据到pms_attr
this.save(attrEntity);
//保存关联关系的数据到pms_attr_attrgroup_relation
//if(attr.getAttrType()==1){ //是基本属性再分组
if(attr.getAttrType()== ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
relationEntity.setAttrGroupId(attr.getAttrGroupId());
relationEntity.setAttrId( attrEntity.getAttrId());
relationDao.insert(relationEntity);
}
}
@Override
public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {
//如果是基本数据信息,那么attr_type是1
/* QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>()
.eq("attr_type","base".equalsIgnoreCase(type)? 1:0); */
QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>()
.eq("attr_type","base".equalsIgnoreCase(type)
? ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode():ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
//查询所有的
if(catelogId != 0){
queryWrapper.eq("catelog_id",catelogId);
}
//有分类的情况
String key = (String) params.get("key");
if(!StringUtils.isEmpty(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
);
PageUtils pageUtils = new PageUtils(page);
//从分页中获取到正在分页的记录
List<AttrEntity> records = page.getRecords();
//映射每一个元素都是attrEntity
final List<AttrRespVo> respVos = records.stream().map((attrEntity) -> {
AttrRespVo attrRespVo = new AttrRespVo();
//把当前attrEntity拷贝到 attrRespVo
BeanUtils.copyProperties(attrEntity, attrRespVo);
//设置分组和分类名称
//通过中间表根据属性id查出分组
//设置分类和分组的名字
if("base".equalsIgnoreCase(type)){//如果是base再设置分组
AttrAttrgroupRelationEntity attrId = relationDao.selectOne(
new QueryWrapper<AttrAttrgroupRelationEntity>()
.eq("attr_id", attrEntity.getAttrId()));
if (attrId != null) {
//获取组id
Long attrGroupId = attrId.getAttrGroupId();
//获取到分组的信息
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
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;
}
@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()){
//设置分组信息
AttrAttrgroupRelationEntity attrgroupRelation = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attrId));
if(attrgroupRelation !=null){
respVo.setAttrGroupId(attrgroupRelation.getAttrGroupId());
//获取分组详情
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupRelation.getAttrGroupId());
if(attrGroupEntity !=null){
respVo.setGroupName(attrGroupEntity.getAttrGroupName());
}
}
}
//设置分类信息
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;
}
@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()) {
//修改分组关联
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);
}
}
}
}
删掉之前添加销售属性也分组的记录
重新新增一个销售属性
刷新中间表的记录没有变化
平台属性查询关联和删除
自己的报错忘记截图,拿视频的
AttrGroupController
@Autowired
AttrService attrService;
@GetMapping("/{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));
//收集所有属性id
List<Long> attrIds = entities.stream().map((attr) -> {
return attr.getAttrId();
}).collect(Collectors.toList());
Collection<AttrEntity> attrEntities = this.listByIds(attrIds);
return (List<AttrEntity>) attrEntities;
}
}
效果
删除关联
AttrGroupController
@PostMapping("/attr/relation/delete")
public R deleteRelation(@RequestBody AttrGroupRelationVo[] vos){
attrService.deleteRelation(vos);
return R.ok();
}
import lombok.Data;
@Data
public class AttrGroupRelationVo {
private Long attrId;
private Long attrGroupId;
}
AttrServiceImpl
@Override
public void deleteRelation(AttrGroupRelationVo[] vos) {
//relationDao.delete(new QueryWrapper<>().eq("attr_id",1L).eq("attr_group_id",1L));
//批量删除
final 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);
}
<!-- delete from pms_attr_attrgroup_relation where (attr_id=#{} and attr_group_id=#{})
or (attr_id=#{} and attr_group_id=#{})-->
<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>
效果,关联--可以移除成功
查询当前分组关联的属性且当前分组是本分类下可以关联的属性,并且是本分类下没有被其他组关联的属性
点击新建关联查询出没有被关联的属性。
AttrGroupController
//查询未被关联的属性
@GetMapping("/{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
/**
* 获取当前分组没有关联的属性
* @param params
* @param attrgroupId
* @return
*/
@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));
final List<Long> collect = group.stream().map(item -> {
return item.getAttrGroupId();
}).collect(Collectors.toList());
//2.2.这些分组关联的属性
List<AttrAttrgroupRelationEntity> groupId = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", collect));
final 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;
}
新增关联-确认新增-选择属性
AttrGroupController
@Autowired
AttrAttrgroupRelationService relationService;
@PostMapping("/attr/relation")
public R addRelation(@RequestBody List<AttrGroupRelationVo> vos){
relationService.saveBatch(vos);
return R.ok();
}
AttrAttrgroupRelationServiceImpl
@Override
public void saveBatch(List<AttrGroupRelationVo> vos) {
final List<AttrAttrgroupRelationEntity> collect = vos.stream().map(item -> {
AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
BeanUtils.copyProperties(item, relationEntity);
return relationEntity;
}).collect(Collectors.toList());
this.saveBatch(collect);
}
在规格参数中添加新属性--机身颜色
确定后空指针异常
queryBaseAttrPage---添加分组不为null的判断再分组
来到规格参数,数据为空
Caused by: org.apache.ibatis.exceptions.TooManyResultsException:
Expected one result (or null) to be returned by selectOne(), but found: 2
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:80) ~[mybatis-3.5.3.jar:3.5.3]
at sun.reflect.GeneratedMethodAccessor113.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_111]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_111]
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426) ~[mybatis-spring-2.0.3.jar:2.0.3]
... 71 common frames omitted
将attr_group_id为null那行数据删掉,刷新数据就出来了。