谷粒商城总结
1.添加修改规格参数
1.在平台属性的规格参数中添加属性
思路
①AttrController处理,并且需要通过VO对象接收前端的数据
②先插入Attr,然后就是获取Attr插入之后的id和前端attr传入的groupid插入relationship表.
AttrService
@Override
public void saveDetail(AttrVo attr) {
//1.保存自己
AttrEntity attrEntity = new AttrEntity();
BeanUtils.copyProperties(attr,attrEntity);
this.save(attrEntity);
//2.保存relationship
AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
relationDao.insert(attrAttrgroupRelationEntity);
}
AttrController
@RequestMapping("/save")
//@RequiresPermissions("product:attr:save")
public R save(@RequestBody AttrVo attr){
attrService.saveDetail(attr);
return R.ok();
}
2.展示规格参数中的属性
思路
①AttrController的接口base/list接收参数并且进行对应的条件查询,主要的操作和之前的分页操作类似
踩坑:
①这里的map通过get方式传输,那么就是一个form类型,而不是一个json类型的数据格式。那么这个地方接收参数类型应该是requestParam而不是reuqestBody。
AttrController
@RequestMapping("base/list/{catelogId}")
public R list(@RequestParam Map<String,Object> params, @PathVariable("catelogId")Long catelogId){
PageUtils data=attrService.qeuryForPage(params,catelogId);
return R.ok().put("page",data);
}
AttrService
@Override
public PageUtils qeuryForPage(Map<String, Object> params, Long catelogId) {
QueryWrapper<AttrEntity> queryWrapper=new QueryWrapper<>();
//1.判断catelogId是否存在
if(catelogId!=0){
queryWrapper.eq("catelog_id",catelogId);
}
//2.key判空
String key = (String) params.get("key");
if(StringUtils.isEmpty(key)){
queryWrapper.and((item)->{
item.eq("attr_id",key).or().like("attr_name",key);
});
}
//
IPage<AttrEntity> page = this.page(
new Query<AttrEntity>().getPage(params),
queryWrapper
);
return new PageUtils(page);
}
3.展示增加的属性分组groupName和分类名称
思路
①在AttrController的base/list接口上面修改
②主要就是通过属性id通过属性和属性分组的中间表获取属性分组id,然后再获取属性分组名称。
③直接通过分类id获取分类名称,因为属性中包含分类id
技术细节
①可以通过stream的map来进行映射,也就是把AttrEntity转换成AttrResVo对象,因为vo对象里面才会保存分组名称和分类名称。
②通过Collections来转换成list。并且返回。
AttrService
@Override
public PageUtils qeuryForPage(Map<String, Object> params, Long catelogId) {
QueryWrapper<AttrEntity> queryWrapper=new QueryWrapper<>();
//1.判断catelogId是否存在
if(catelogId!=0){
queryWrapper.eq("catelog_id",catelogId);
}
//2.key判空
String key = (String) params.get("key");
if(StringUtils.isEmpty(key)){
queryWrapper.and((item)->{
item.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);
//1.查询分组name,先查询分组id
List<AttrEntity> records = page.getRecords();
List<AttrResVo> collect = records.stream().map((attrEntity -> {
//0.创建vo对象
AttrResVo attrResVo = new AttrResVo();
BeanUtils.copyProperties(attrEntity, attrResVo);
System.out.println(attrEntity);
//1.查询groupId
AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
System.out.println(relationEntity);
//2.根据groupid查询groupname
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
//3.如果name不为空那么就set
if (attrGroupEntity.getAttrGroupName() != null) {
attrResVo.setGroupName(attrGroupEntity.getAttrGroupName());
}
//4.直接查询分类名称
CategoryEntity categoryEntity = categoryDao.selectOne(new QueryWrapper<CategoryEntity>().eq("cat_id", attrResVo.getCatelogId()));
if (categoryEntity.getName() != null) {
attrResVo.setCatelogName(categoryEntity.getName());
}
return attrResVo;
})).collect(Collectors.toList());
//最后设置到page中返回
pageUtils.setList(collect);
return pageUtils;
}
4.修改回显问题(分类信息需要进行回显,属性分组也需要进行回显)
思路
①修改AttrController->处理info接口->调用service一个自定义方法->获取AttrVo(需要增加catelogPath)对象
②先根据id获取AttrEntiry对象,然后entity对象转换成vo对象,然后就是根据参数attrId获取relationship对象(属性与属性分组),接着就是获取groupId->最后就能根据groupid获取分组对象->setname进vo对象
③然后就是根据AttrResVo下面的catelogId查询分类对象和catelogPath。
④前端查询回显
AttrService
@Override
public AttrResVo getVoById(Long attrId) {
//0.创建VO传输
AttrResVo attrResVo=new AttrResVo();
AttrEntity attrEntity = this.getById(attrId);
BeanUtils.copyProperties(attrEntity,attrResVo);
//1.查询分组id和分组name
//2.根据attrid查询relationship
AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
//3.判空,并且setgroupId
if(relationEntity!=null){
attrResVo.setAttrGroupId(relationEntity.getAttrGroupId());
//4.根据groupId查询group
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
if(attrGroupEntity!=null){
attrResVo.setGroupName(attrGroupEntity.getAttrGroupName());
}
}
//1.获取attr对应的分类id
Long catelogId = attrResVo.getCatelogId();
//2.根据id查询分类path
Long[] catelogPath = categoryService.findCatelogPath(catelogId);
//3.set 进vo
attrResVo.setCatelogPath(catelogPath);
//4.根据id获取对象
CategoryEntity categoryEntity = categoryService.getById(catelogId);
//5.如果不是空那么就把name set进去
if(categoryEntity!=null){
attrResVo.setCatelogName(categoryEntity.getName());
}
//6.返回对象
return attrResVo;
}
5.属性修改不成功->实际上是传入对象没有包含分组关联属性。
思路
①在AttrController中修改info->传入对象是AttrVo,具有分组id
②在service中进行修改处理。
③如果发现attrid的关联数据>0那么就更新,如果不是那么就插入属性与分组的关联关系。(比原来多了这个更新关联操作.)
AttrService
@Override
public void updateAttrVo(AttrVo attr) {
//1.创建PO对象赋值更新
AttrEntity attrEntity=new AttrEntity();
BeanUtils.copyProperties(attr,attrEntity);
this.updateById(attrEntity);
//2.修改分组关联
//3.先获取这个关联
Long attrId = attr.getAttrId();
//4.根据attrId获取关联count
Integer count = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
//5.创建relation对象
AttrAttrgroupRelationEntity relationEntity=new AttrAttrgroupRelationEntity();
Long attrGroupId = attr.getAttrGroupId();
relationEntity.setAttrId(attrId);
relationEntity.setAttrGroupId(attrGroupId);
if(count>0){
//1.如果存在那么就进行更新
relationDao.update(relationEntity,new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attrId));
}else{
//2.如果不存在那么就插入
relationDao.insert(relationEntity);
}
}
2.维护销售属性
1.显示销售属性
遇到的问题:
①规格属性和销售属性不同处理:路径上面的{type}/list/{catelog}
②销售属性没有对应的属性分组
思路
①修改AttrCon的list路径
②service的查询方法需要接收type参数,加入到条件查询。
③如果type==base的时候才进行分组查询。
AttrService
@Override
public PageUtils qeuryForPage(Map<String, Object> params, Long catelogId, String type) {
//0.判断类型
QueryWrapper<AttrEntity> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("attr_type","base".equalsIgnoreCase(type)?1:0);
//1.判断catelogId是否存在
if(catelogId!=0){
queryWrapper.eq("catelog_id",catelogId);
}
//2.key判空
String key = (String) params.get("key");
if(StringUtils.isEmpty(key)){
queryWrapper.and((item)->{
item.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);
//1.查询分组name,先查询分组id
List<AttrEntity> records = page.getRecords();
List<AttrResVo> collect = records.stream().map((attrEntity -> {
//0.创建vo对象
AttrResVo attrResVo = new AttrResVo();
BeanUtils.copyProperties(attrEntity, attrResVo);
System.out.println(attrEntity);
//1.查询groupId,而且如果是base的时候才会查询属性分组
if("base".equalsIgnoreCase(type)){
AttrAttrgroupRelationEntity relationEntity = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
System.out.println(relationEntity);
if(relationEntity!=null){
//2.根据groupid查询groupname
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(relationEntity.getAttrGroupId());
//3.如果name不为空那么就set
if(attrGroupEntity!=null){
attrResVo.setGroupName(attrGroupEntity.getAttrGroupName());
}
}
}
//4.直接查询分类名称
CategoryEntity categoryEntity = categoryDao.selectOne(new QueryWrapper<CategoryEntity>().eq("cat_id", attrResVo.getCatelogId()));
if (categoryEntity != null) {
attrResVo.setCatelogName(categoryEntity.getName());
}
return attrResVo;
})).collect(Collectors.toList());
//最后设置到page中返回
pageUtils.setList(collect);
return pageUtils;
}
2.保存销售属性不保存到分组关联
思路
①添加一个常量类保存base和sale的code
②在save、update、getInfo等需要判断是不是base类型也就是规格属性才进行保存或者是获取。
3.属性分组下的属性维护
1.查询属性分组下面的属性
思路
①AttrGroupCon注入AttrService。然后调用getRelationshipAttr
②根据groupId在关系表中查询所有attrId(通过流的方式来把entity转换成ids)
③接着就是根据获取的attrId集合来查询所有的属性集合
AttrController
@RequestMapping("{attrGroupId}/attr/relation")
public R attrRelation(@PathVariable("attrGroupId")Long attrGroupId){
List<AttrEntity> data=attrService.getRelationAttr(attrGroupId);
return R.ok().put("data",data);
}
AttrService
//根据分组id查询下面所有的属性
@Override
public List<AttrEntity> getRelationAttr(Long attrGroupId) {
//1.根据分组id查询对应的属性id
QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("attr_group_id",attrGroupId);
List<AttrAttrgroupRelationEntity> relationEntities = relationDao.selectList(queryWrapper);
//2.获取attrId集合
List<Long> collect = relationEntities.stream().map((item) -> {
return item.getAttrId();
}).collect(Collectors.toList());
//3.通过查询集合Ids获取对应的属性
Collection<AttrEntity> attrEntities = this.listByIds(collect);
return (List<AttrEntity>) attrEntities;
}
2.删除属性分组与属性的关联
思路
①创建接收的AttrRelationVo对象
②接着就是编写attr/relation/delete接口,在servcie先把vo->po。然后交给AttrDao处理
③自己编写一个删除语句,通过拼接语句进行删除。拼接方法就是foreach
AttrDao.xml(删除语句)
<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>
AttrService
//批量删除与分组下的属性
@Override
public void deleteRelation(AttrGroupRelationVo[] vos) {
//1.先把vos转换成relation
List<AttrAttrgroupRelationEntity> collect = Arrays.asList(vos).stream().map((item) -> {
AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
BeanUtils.copyProperties(item, attrAttrgroupRelationEntity);
return attrAttrgroupRelationEntity;
}).collect(Collectors.toList());
//2.把这个list交给base处理。
baseMapper.deleteBatchRelation(collect);
}
总结:批量删除可以通过or进行拼接删除。
3.新建关联的时候,如果没有属性与这个属性分组关联,那么ids就是null的,这个时候就需要在getRelation的时候进行判空处理,避免空指针异常。
4.属性分组展示可以关联的属性
思路
①可以关联的属性特点是(1)处于属性分组的分类,而且type一定是base(2)其它属性分组没有关联的属性
②先查询分类id
③查询其他属性分组,sql语句条件(1)不是本分组id(2)在本分组的分类
④map获取其它分组的id,并且通过relationDao来查询他们关联的属性
⑤查询不等于这些属性id的属性,而且分类与属性分组相同。
AttrGroupController
/**
* 根据分组id查询所有可以关联的属性
* @param attrGroupId
* @return
*/
@RequestMapping("{attrGroupId}/noattr/relation")
public R attrNoRelation(@PathVariable("attrGroupId")Long attrGroupId,
@RequestParam Map<String,Object> params){
PageUtils data= attrService.getNoRelationAttr(attrGroupId,params);
return R.ok().put("page",data);
}
AttrService
@Override
public PageUtils getNoRelationAttr(Long attrGroupId, Map<String, Object> params) {
//1.根据groupid查询对应的分类id,group中对应着分类id
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
Long catelogId = attrGroupEntity.getCatelogId();
//2.查询其他分类已经占有的属性
//3.查询其他分类,条件就是
// ①不是这个分组id②而且是这个分类的属性分组,而且类型是基本属性
//查询其它分组
List<AttrGroupEntity> othersGroup = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().ne("attr_group_id", attrGroupId).eq("catelog_id",catelogId));
//4.查询这些分组的关联属性id
//5.先获取这些分组的id,分类的其它分组
//获取其它分组id
List<Long> groupIds = othersGroup.stream().map((item) -> {
return item.getAttrGroupId();
}).collect(Collectors.toList());
//6.先查询otherGroup的属性id
//通过relation
List<AttrAttrgroupRelationEntity> relationEntities = relationDao.selectList(
new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id",groupIds)
);
//7.获取属性ids.
List<Long> attrIds = relationEntities.stream().map((item) -> {
return item.getAttrId();
}).collect(Collectors.toList());
QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<>();
//查询同分类下同type的可关联属性。
queryWrapper.eq("catelog_id",catelogId).eq("attr_type",ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
if(attrIds!=null&&attrIds.size()>0){
queryWrapper.notIn("attr_id",attrIds);
}
//key判空
String key = (String) params.get("key");
if(!StringUtils.isEmpty(key)){
queryWrapper.and((item)->{
item.eq("attr_id",key).or().like("attr_name",key);
});
}
//分页查询
IPage<AttrEntity> page = this.page(
new Query<AttrEntity>().getPage(params),
queryWrapper
);
log.info(String.valueOf(page.getRecords()));
return new PageUtils(page);
}
5.保存属性和属性分组的关联
思路
①AttrGroupCon中处理
②获取groupId和attrId的AttrGroupRelationVo的集合,然后交给service
③relationService把vo->po,接着就是调用saveBatch
AttrGroupController
/**
* 保存属性和属性分组的关联
* @param vos
* @return
*/
@RequestMapping("attr/relation")
public R addRelation(@RequestBody List<AttrGroupRelationVo> vos){
relationService.saveRelation(vos);
return R.ok();
}
AttrAttrGroupService
@Override
public void saveRelation(List<AttrGroupRelationVo> vos) {
//1.先把vos转换成po
List<AttrAttrgroupRelationEntity> relationEntities = vos.stream().map(item -> {
AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
BeanUtils.copyProperties(item, relationEntity);
return relationEntity;
}).collect(Collectors.toList());
//存入之前需要判断之前是否存在这个relation。
//2.批量存入
this.saveBatch(relationEntities);
}
遇到的bug:
①添加规格属性,发生关联,发现会连续存入两次关联关系。
原因:其实就是因为添加规格属性的时候顺便也把空的属性分组和属性关联了。然后属性与属性分组发生关联的时候又再次加入,原因前一次加入的关联没有属性分组,也就是每次都能够在新增的关联中出现(因为attrId会出现两个)。