电商项目——初识电商——第一章——上篇
电商项目——分布式基础概念和电商项目微服务架构图,划分图的详解——第二章——上篇
电商项目——电商项目的虚拟机环境搭建_VirtualBox,Vagrant——第三章——上篇
电商项目——Linux虚拟机中安装docker,mysql,redis_VirtualBox——第四章——上篇
电商项目——电商项目的环境搭建_开发工具&环境搭建——第五章——上篇
电商项目——快速开发人人开源搭建后台管理系统&代码生成器逆向工程搭建——第六章——上篇
电商项目——分布式组件(SpringCloud Alibaba,SpringCloud)——第七章——上篇
电商项目——前端基础——第八章——上篇
电商项目——商品服务-API-三级分类——第九章——上篇
电商项目——商品服务-API-品牌管理——第十章——上篇
电商项目——商品服务-API-属性分组——第十一章——上篇
电商项目——商品服务-API-品牌管理——第十二章——上篇
电商项目——商品服务-API-平台属性——第十三章——上篇
电商项目——商品服务-API-新增商品——第十四章——上篇
电商项目——商品服务-API-商品管理——第十五章——上篇
电商项目——商品服务-API-仓库管理——第十六章——上篇
1:规格参数新增与VO
AttrGroupController .java
@RestController
@RequestMapping("product/attrgroup")
public class AttrGroupController {
@Autowired
private AttrGroupService attrGroupService;
@Autowired
private CategoryService categoryService;
/**
* 列表
*/
@RequestMapping("/list/{catelogId}")
//路径变量的id,我们要使用@PathVariable来标明它是一个路径
public R list(@RequestParam Map<String, Object> params,@PathVariable Long catelogId){
PageUtils page = attrGroupService.queryPage(params,catelogId);
return R.ok().put("page", page);
}
AttrGroupServiceImpl
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {
@Override
public PageUtils queryPage(Map<String, Object> params, Long catelogId) {
//Map<String, Object> params中如果传入的参数由key(模糊匹配)
//select * from pms_attr_group where catelog_id=? and (att_group_id=key or att_group_name like %key%)
String key= (String) params.get("key");
//让三级分类的id,等于我传过来的指定值
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);
});
}
//如果catelogId等于0就是查所有,不是等于0就是查指定的
if (catelogId==0){
//当前类有一个默认生成的方法page,传入两个参数(分页信息,查询信息)
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);
}
}
新增一个数据发生如下问题
解决办法:我们编写一个AttrVo类,什么是VO,我们如下文章
Object划分
AttrVo.java
@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;
//新增一个分组id
private Long AttrGroupId;
}
AttrController .java
@RestController
@RequestMapping("product/attr")
public class AttrController {
/**
* 保存
*/
@RequestMapping("/save")
// @RequiresPermissions("product:attr:save")
public R save(@RequestBody AttrVo attr){
attrService.saveAttr(attr);
return R.ok();
}
AttrServiceImpl .java
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
@Override
public void saveAttr(AttrVo attr) {
AttrEntity attrEntity=new AttrEntity();
//1:保存基本数据
//将页面attr来的值最后封装到attrEntity中
BeanUtils.copyProperties(attr,attrEntity);
this.save(attrEntity);
//2:保存关联关系
AttrAttrgroupRelationEntity attrAttrgroupRelationEntity=new AttrAttrgroupRelationEntity();
attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
relationDao.insert(attrAttrgroupRelationEntity);
}
2:规格参数列表
我们编写查询规格参数列表功能
AttrController .java
@RestController
@RequestMapping("product/attr")
public class AttrController {
@Autowired
private AttrService attrService;
/**
* 实现模糊查询和字段查询//attr_id attr_name catelogId
* @param params
* @param catelogId
* @return
*/
@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); }
AttrServiceImpl .java
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
@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);
});
}
//我们调用this.page方法先将分页条件封装成IPage参数
IPage<AttrEntity> page = this.page(
new Query<AttrEntity>().getPage(params),
queryWrapper
);
return new PageUtils(page);
}
我们不推荐使用连表查询(左右连接)
AttrServiceImpl .java
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
@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);
});
}
//我们调用this.page方法先将分页条件封装成IPage参数
IPage<AttrEntity> page = this.page(
new Query<AttrEntity>().getPage(params),
queryWrapper
);
PageUtils pageUtils = new PageUtils(page);
//从真正获取到的page里面获取到查询记录
List<AttrEntity> records = page.getRecords();
//使用流失编程
List<AttrRespVo> attrRespVos = 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 attr_group_id = attrGroupDao.selectOne(new QueryWrapper<AttrGroupEntity>().eq("attr_group_id", attrId.getAttrGroupId()));
attrRespVo.setGroupName(attr_group_id.getAttrGroupName());
}
CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
if (categoryEntity != null) {
attrRespVo.setGroupName(categoryEntity.getName());
}
return attrRespVo;
}).collect(Collectors.toList());
pageUtils.setList(attrRespVos);
return pageUtils;
}
3:规格修改
我们接下来完成规格参数中的修改功能
AttrController
@RestController
@RequestMapping("product/attr")
public class AttrController {
/**
* 信息
*/
@RequestMapping("/info/{attrId}")
// @RequiresPermissions("product:attr:info")
public R info(@PathVariable("attrId") Long attrId){
//AttrEntity返回的数据太少了,我们用自己的vo
// AttrEntity attr = attrService.getById(attrId);
AttrRespVo attr=attrService.getAttrInfo(attrId);
return R.ok().put("attr", attr);
}
AttrServiceImpl .java
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
@Override
public AttrRespVo getAttrInfo(Long attrId) {
AttrRespVo respVo=new AttrRespVo();
AttrEntity attrEntity = this.getById(attrId);
BeanUtils.copyProperties(attrEntity,respVo);
//1,设置分组信息
AttrAttrgroupRelationEntity attrgroupRelation= relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrId));
if (attrgroupRelation!=null) {
respVo.setAttrGroupId(attrgroupRelation.getAttrGroupId());
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(new QueryWrapper<AttrGroupEntity>().eq("attr_group_id", 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);
respVo.setCatelogName(categoryEntity.getName());
return respVo;
}
AttrRespVo .java
@Data
public class AttrRespVo extends AttrVo {
/**
* "catelogName": "手机/数码/手机", //所属分类名字
"groupName": "主体", //所属分组名字
*/
private String catelogName;
private String groupName;
private Long[] catelogPath;
}
我们继续完善修改功能
AttrController
@RestController
@RequestMapping("product/attr")
public class AttrController {
/**
* 修改
*/
@RequestMapping("/update")
// @RequiresPermissions("product:attr:update")
public R update(@RequestBody AttrVo attr){
attrService.updateAttr(attr);
return R.ok();
}
AttrServiceImpl
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
@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 integer = relationDao.selectCount(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attr.getAttrId()));
if (integer>0){
relationDao.update(relationEntity,new UpdateWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attr.getAttrId()));
}else {
relationDao.insert(relationEntity);
}
}
4:销售属性维护
AttrController
@RestController
@RequestMapping("product/attr")
public class AttrController {
/**
* 实现模糊查询和字段查询//attr_id attr_name catelogId
* @param params
* @param catelogId
* @return
*/
@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); }
AttrServiceImpl.java
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
@Override
public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {
QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().eq("attr_type","base".equalsIgnoreCase(type)?1:0);
if (catelogId!=0){
//基本属性等于1否则就是0(类型是基本类型就查1,否则就查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);
});
}
//我们调用this.page方法先将分页条件封装成IPage参数
IPage<AttrEntity> page = this.page(
new Query<AttrEntity>().getPage(params),
queryWrapper
);
PageUtils pageUtils = new PageUtils(page);
//从真正获取到的page里面获取到查询记录
List<AttrEntity> records = page.getRecords();
//使用流失编程
List<AttrRespVo> attrRespVos = 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 ("base".equalsIgnoreCase(type)) {
AttrAttrgroupRelationEntity attrId = relationDao.selectOne(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId()));
if (attrId != null) {
AttrGroupEntity attr_group_id = attrGroupDao.selectOne(new QueryWrapper<AttrGroupEntity>().eq("attr_group_id", attrId.getAttrGroupId()));
attrRespVo.setGroupName(attr_group_id.getAttrGroupName());
}
}
CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
if (categoryEntity != null) {
attrRespVo.setCatelogName(categoryEntity.getName());
}
return attrRespVo;
}).collect(Collectors.toList());
pageUtils.setList(attrRespVos);
return pageUtils;
}
//只有是基本属性才要保存分组关系,销售属性不用保存分组关系
@Transactional
@Override
public void saveAttr(AttrVo attr) {
AttrEntity attrEntity=new AttrEntity();
//1:保存基本数据
//将页面attr来的值最后封装到attrEntity中
BeanUtils.copyProperties(attr,attrEntity);
this.save(attrEntity);
//2:保存关联关系
//只有是基本属性才要保存分组关系,销售属性不用保存分组关系
if (attr.getAttrType()==1){
AttrAttrgroupRelationEntity attrAttrgroupRelationEntity=new AttrAttrgroupRelationEntity();
attrAttrgroupRelationEntity.setAttrGroupId(attr.getAttrGroupId());
attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
relationDao.insert(attrAttrgroupRelationEntity);
}
我们经常要判断属性的类型,所以我们要写一个常量在mall-common中
if (attr.getAttrType()== ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
QueryWrapper<AttrEntity> queryWrapper = new QueryWrapper<AttrEntity>().eq("attr_type","base".equalsIgnoreCase(type)?ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode():ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());
这样数据库以后如果更改一些规则了,我们只需要修改枚举类,就不需要修改各处引用的代码
- 这个类下的所有方法都要判断只有是基本属性才要保存分组关系,销售属性不用保存分组关系
5 :查询分组关联属性&删除关联
我们再来编写分组与属性分组关联的功能
AttrGroupController
@RestController
@RequestMapping("product/attrgroup")
public class AttrGroupController {
@Autowired
private AttrGroupService attrGroupService;
@Autowired
AttrService attrService;
@Autowired
private CategoryService categoryService;
@GetMapping("/{attrgroupId}/attr/relation")
public R attrRelation(@PathVariable("attrgroupId") Long attrgroupId ){
List<AttrEntity> entities=attrService.getRelationAttr(attrgroupId);
return R.ok().put("data",entities);
}
AttrServiceImpl
@Slf4j
@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {
/**
* 根据分组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());
//查询到所有关联表中的属性id,调用如下方法查出所有属性表中的值
Collection<AttrEntity> attrEntities = this.listByIds(attrIds);
return (List<AttrEntity>) attrEntities;
}
编写如下功能
@RestController
@RequestMapping("product/attrgroup")
public class AttrGroupController {
@Autowired
private AttrGroupService attrGroupService;
@Autowired
AttrService attrService;
@Autowired
private CategoryService categoryService;
@PostMapping("/attr/relation/delete")
///product/attrgroup/attr/relation/delete
public R deleteRelation(AttrAttrgroupRelationEntity[] vos ){
attrService.deleteRelation(vos);
return R.ok();
}
AttrServiceImpl
@Override
public void deleteRelation(AttrAttrgroupRelationEntity[] vos) {
//我们要实现只发一次请求,完成批量删除
// relationDao.delete(new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",1L).eq("attr_group_id",1l));
//把两个数组,变成AttrAttrgroupRelationEntity的集合
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 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>
6:查询分组未关联的属性
完成如下操作
AttrGroupController .java
@RestController
@RequestMapping("product/attrgroup")
public class AttrGroupController {
///product/attrgroup/{attrgroupId}/noattr/relation
@GetMapping("{attrgroupId}/noattr/relation")
public R attrNoRelation(@PathVariable("attrgroupId") Long attrgroupId,@RequestParam Map<String,Object> param) {
PageUtils page =attrService.getNoRelationAttr(attrgroupId,param);
return R.ok().put("page",page);
}
AttrServiceImpl
/***
* 获取当前分组没有关联的属性
* @param attrgroupId
* @param param
* @return
*/
@Override
public PageUtils getNoRelationAttr(Long attrgroupId, Map<String, Object> param) {
//1:当前分组只可以关联自己所属的三级分类里面的所有属性
AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
//以后只可以查该三级分类下的id
Long catelogId = attrGroupEntity.getCatelogId();
//2:当前分组只可以关联别的分组没有引用的属性
//2.1)当前分类下的其他分组
List<AttrGroupEntity> group = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
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));
List<Long> attrIds = groupId.stream().map((Item) -> {
return Item.getAttrId();
}).collect(Collectors.toList());
//2.3 从当前分类的所有属性中移除这些属性
// List<AttrEntity> attrEntities = this.baseMapper.selectList(new QueryWrapper<AttrEntity>().eq("catelog_Id", catelogId).notIn("attr_id", attrIds));
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) param.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(param), wrapper);
PageUtils pageUtils = new PageUtils(page);
return pageUtils;
}
7:新增分组与属性关联
AttrGroupController
@RestController
@RequestMapping("product/attrgroup")
public class AttrGroupController {
///product/attrgroup/attr/relation
@PostMapping("/attr/relation")
public R addRelation(@RequestBody List<AttrGroupRelationVo> vos){
relationService.saveBatch(vos);
return R.ok();
}
AttrAttrgroupRelationServiceImpl .java
public class AttrAttrgroupRelationServiceImpl extends ServiceImpl<AttrAttrgroupRelationDao, AttrAttrgroupRelationEntity> implements AttrAttrgroupRelationService {
@Override
public void saveBatch(List<AttrGroupRelationVo> vos) {
//执行批量保存:
//原理:我们使用的vo数据要转化成AttrAttrgroupRelationEntity才可以执行批量保存
List<AttrAttrgroupRelationEntity> collect = vos.stream().map((item) -> {
AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
BeanUtils.copyProperties(item, relationEntity);
return relationEntity;
}).collect(Collectors.toList());
this.saveBatch(collect);
}