Chapter V: goods and services - platform attributes
1, Attribute grouping
1. Introduction of front end
1. Copy the code summary of the front end into VScode
2. Because the data encapsulated in the controller's @ RequestMapping("/list/tree") is date, you need to change the data.data of the front-end code to data.date
3. Description:
attrgroup is a form for the entire page
category is a tree menu tree on the left
Attrgroup add or update is to add or modify grouping information
Attr group relation is association
2. Back end adding method
1. Add a method to obtain the grouping attribute
1) Add a get list for AttrGroupController and get grouping properties by id
That is, click the three-level menu on the left, and the corresponding attributes will be obtained on the right
/** * list */ @RequestMapping("/list/") public R list(@RequestParam Map<String, Object> params, @PathVariable("catelogId") Long catelogId){ // PageUtils page = attrGroupService.queryPage(params); PageUtils page = attrGroupService.queryPage(params, catelogId); return R.ok().put("page", page); }
2) Add implementation class method
@Override public PageUtils queryPage(Map<String, Object> params, Long catelogId) { if (catelogId == 0) { IPage<AttrGroupEntity> page = this.page( new Query<AttrGroupEntity>().getPage(params), new QueryWrapper<AttrGroupEntity>() ); return new PageUtils(page); } else { String key = (String) params.get("key"); QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId); if (!StringUtils.isEmpty(key)) { wrapper.and((obj) -> { obj.eq("attr_group_id", key) .or() .like("attr_group_name", key); }); } IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params),wrapper); return new PageUtils(page); } }
2. Adding a group
1) When adding a new category, the category in the third episode should not contain sub categories, so add a sub category group to the CategoryEntity. When it is empty, it will not be transferred to json
//Sub classification @JsonInclude(JsonInclude.Include.NON_EMPTY) @TableField(exist = false) private List<CategoryEntity> children;
2) Add controller for incoming data for AttrGroupController
@Resource private CategoryService categoryService; /** * information */ @RequestMapping("/info/") public R info(@PathVariable("attrGroupId") Long attrGroupId){ AttrGroupEntity attrGroup = attrGroupService.getById(attrGroupId); Long catelogId = attrGroup.getCatelogId(); Long[] path = categoryService.findCategoryPath(catelogId); attrGroup.setCatelogPath(path); return R.ok().put("attrGroup", attrGroup); }
3) Add warehouse Path for AttrGroupEntity
@TableField(exist = false) private Long[] catelogPath;
4) Add implementation class
//Find the full path of cateLogId @Override public Long[] findCategoryPath(Long catelogId) { List<Long> paths = new ArrayList<>(); List<Long> parentPath = findParentPath(catelogId, paths); Collections.reverse(parentPath); return parentPath.toArray(new Long[parentPath.size()]); } //225,25,2 private List<Long> findParentPath(Long catelogId, List<Long> paths) { //1. Collect current node id paths.add(catelogId); CategoryEntity byId = this.getById(catelogId); if (byId.getParentCid() != 0) { findParentPath(byId.getParentCid(), paths); } return paths; }
3. Test
2, Cascade update
1. Add paging
Note: add event control
@Configuration @EnableTransactionManagement @MapperScan("con.yangyan.gulimall.product.dao") public class MyBatisConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2)); return interceptor; } }
Gets the paging information
2. Association classification
1. Get the classification list associated with the current brand
/** * Get the current brand association classification list */ // @RequestMapping(value = "category/list",method = RequestMethod.GET) @GetMapping(value = "category/list") public R categoryList(@RequestParam("brandId") Long brandId){ List<CategoryBrandRelationEntity> data = categoryBrandRelationService.list( new QueryWrapper<CategoryBrandRelationEntity>().eq("brand_id",brandId) ); return R.ok().put("data", data); }
2. Add classification
Because the data passed in from the database is only ID and brand_ ID and catalog_ ID, because brand needs to be added_ Name and catalog_ name
Modify the controller of save
1) Change the method to saveDetail
/** * preservation */ @RequestMapping("/save") public R save(@RequestBody CategoryBrandRelationEntity categoryBrandRelation){ categoryBrandRelationService.saveDetail(categoryBrandRelation); return R.ok(); }
2) Implementation method
@Override public void saveDetail(CategoryBrandRelationEntity categoryBrandRelation) { Long brandId = categoryBrandRelation.getBrandId(); Long catelogId = categoryBrandRelation.getCatelogId(); BrandEntity brandEntity = brandDao.selectById(brandId); CategoryEntity categoryEntity = categoryDao.selectById(catelogId); categoryBrandRelation.setBrandName(brandEntity.getName()); categoryBrandRelation.setCatelogName(categoryEntity.getName()); this.save(categoryBrandRelation); }
3) When modifying the brand table, the data changes, and the data of other tables should also be changed. Therefore, the updata method should be modified
Modify the association with the brand (method 1)
Modify brand controller
/** * modify */ @RequestMapping("/update") public R update(@Validated() @RequestBody BrandEntity brand){ brandService.updateDetail(brand); return R.ok(); }
Modify the implementation class of brand modification
@Resource CategoryBrandRelationService categoryBrandRelationService; @Transactional @Override public void updateDetail(BrandEntity brand) { this.updateById(brand); if (!StringUtils.isEmpty(brand.getName())){ //The brand name information in the categoryBrandRelation table will be updated synchronously categoryBrandRelationService.updateBrand(brand.getBrandId(),brand.getName()); //TODO update other management } }
Add, modify and update the name of the bound service through mybatis puls
@Override public void updateBrand(Long brandId, String name) { CategoryBrandRelationEntity relationEntity = new CategoryBrandRelationEntity(); relationEntity.setBrandId(brandId); relationEntity.setBrandName(name); this.update(relationEntity,new UpdateWrapper<CategoryBrandRelationEntity>().eq("brand_id",brandId)); }
4) Cascade update category (method 2)
Modify brand controller
/** * modify */ @RequestMapping("/update") public R update(@RequestBody CategoryEntity category){ categoryService.updateCascade(category); return R.ok(); }
Implementation method
//Cascade update all associated data @Transactional @Override public void updateCascade(CategoryEntity category) { this.updateById(category); if (!StringUtils.isEmpty(category.getName())){ categoryBrandRelationService.updateCategory(category.getCatId(),category.getName()); } }
Add a method to update the name of the bound service
@Override public void updateCategory(Long catId, String name) { this.baseMapper.updateCategory(catId,name); }
Update with sql statement
@Mapper public interface CategoryBrandRelationDao extends BaseMapper<CategoryBrandRelationEntity> { void updateCategory(@Param("ID") Long catId,@Param("catelog_name") String name); }
<update id="updateCategory"> UPDATE `pms_category_brand_relation` SET catelog_name=# WHERE catelog_id=#; </update>3, Specification parameters
1. Adjust attribute grouping interface
Adjust fuzzy query function
@Override public PageUtils queryPage(Map<String, Object> params, Long catelogId) { String key = (String) params.get("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 { IPage<AttrGroupEntity> page = this.page(new Query<AttrGroupEntity>().getPage(params) , wrapper.eq("catelog_id", catelogId)); return new PageUtils(page); } }
2. Adding specification parameters
1. Add VO entity class of attr
2. Modify the new controller and method
/** * preservation */ @RequestMapping("/save") public R save(@RequestBody AttrVo attr){ attrService.saveAttr(attr); return R.ok(); }
@Resource AttrAttrgroupRelationDao relationDao; @Transactional @Override public void saveAttr(AttrVo attr) { AttrEntity attrEntity = new AttrEntity(); BeanUtils.copyProperties(attr,attrEntity); this.save(attrEntity); AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity(); relationEntity.setAttrGroupId(attr.getAttrGroupId()); relationEntity.setAttrId(attrEntity.getAttrId()); relationDao.insert(relationEntity); }
3. Parameter specification list
Also modify the controller and implementation classes
/** * Get list */ @GetMapping("/base/list/") public R baseAttrList(@RequestParam Map<String, Object> params , @PathVariable("catelogId") Long catelogId){ PageUtils page = attrService.queryBaseAttrPage(params ,catelogId); return R.ok().put("page", page); }
@Resource AttrAttrgroupRelationDao relationDao; @Resource AttrGroupDao attrGroupDao; @Resource CategoryDao categoryDao; @Override public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId) { QueryWrapper<AttrEntity> wrapper = new QueryWrapper<>(); if (catelogId !=0){ wrapper.eq("catelog_id",catelogId); } String key =(String) params.get("key"); if (!StringUtils.isEmpty(key)) { wrapper.and((obj) -> { obj.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); 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()) ); 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; }
4. Modification of specifications and parameters
1 set echo of parameters
/** * information */ @RequestMapping("/info/") public R info(@PathVariable("attrId") Long attrId){ // AttrEntity attr = attrService.getById(attrId); AttrRespVo respVo = attrService.getAttrInfo(attrId); return R.ok().put("attr", respVo); }
@Resource CategoryService categoryService; @Override public AttrRespVo getAttrInfo(Long attrId) { AttrRespVo respVo = new AttrRespVo(); AttrEntity attrEntity = this.getById(attrId); BeanUtils.copyProperties(attrEntity,respVo); //Set grouping AttrAttrgroupRelationEntity attrgroupRelationEntity = relationDao.selectOne( new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id",attrId)); if (attrgroupRelationEntity!= null){ respVo.setAttrGroupId(attrgroupRelationEntity.getAttrGroupId()); AttrGroupEntity attrGroupEntity = attrGroupDao.selectById( attrgroupRelationEntity.getAttrGroupId()); if (attrGroupEntity!=null){ respVo.setGroupName(attrGroupEntity.getAttrGroupName()); } } //Set classification information Long catelogId = attrEntity.getCatelogId(); Long[] categoryPath = categoryService.findCategoryPath(catelogId); respVo.setCatelogPath(categoryPath); CategoryEntity categoryEntity = categoryDao.selectById(catelogId); if (categoryEntity!= null){ respVo.setCatelogName(categoryEntity.getName()); } return respVo; }
Note: there may be no value in the table_ You need to change the table yourself
4, Sales attributes1 get list
Obtain the sales attributes by extracting the data from the specification list
1. Change the address of baseAttrList to a parameter , and reconstruct the method
@GetMapping("//list/") 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); }
2. Modify the initialization query of queryBaseAttrPage method
QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("attr_type","base".equalsIgnoreCase(type)?1:0);
2. Add sales attribute
It is found that the specification parameters and sales attributes share a save method, which will save the data into the relation ship
Modify the save method so that when the type is 1, it will not be saved
AttrEntity attrEntity = new AttrEntity(); BeanUtils.copyProperties(attr, attrEntity); this.save(attrEntity); if (attr.getAttrType() == 1){ AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity(); relationEntity.setAttrGroupId(attr.getAttrGroupId()); relationEntity.setAttrId(attrEntity.getAttrId()); relationDao.insert(relationEntity); }
Similarly, because the distinction between sales attributes and procedure parameters is often used, it is often quantified in common.
public class ProductConstant { public enum AttrEnum{ ATTR_TYPE_BASE(1,"Basic properties"),ATTR_TYPE_SALE(0,"Sales attributes"); 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; } } }
Modify the parameter in attrServiceImpl to a constant
5, Associated specification properties1. Get association properties
@Resource private AttrService attrService; //2/attr/relation @GetMapping("//attr/relation") public R attrRelation(@PathVariable("attrgroupId") Long attrgroupId){ List<AttrEntity> entities = attrService.getRelationAttr(attrgroupId); return R.ok().put("data",entities); }
/** * Find all the associated basic attributes according to the group 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; }
2. Delete association method
package com.yangyan.gulimall.product.controller; @PostMapping("/attr/relation/delete") public R deleteRelation(@RequestBody AttrGroupRelationVo[] vos){ attrService.deleteRelation(vos); return R.ok(); }
@Override public void deleteRelation(AttrGroupRelationVo[] vos) { //relationDao.delete(new QueryWrapper<>().eq("attr_id",1L).eq("attr_group_id",1L)); // 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); }
@Mapper public interface AttrAttrgroupRelationDao extends BaseMapper<AttrAttrgroupRelationEntity> { 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 = # AND attr_group_id=#) </foreach> </delete>
3. Get all attributes not obtained by the group
///product/attrgroup//noattr/relation @GetMapping("//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); }
/** * Gets all properties not associated with the current group * @param params * @param attrgroupId * @return */ @Override public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) { //1. The current group can only be associated with all attributes in the category to which it belongs AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId); Long catelogId = attrGroupEntity.getCatelogId(); //2. The current group can only be associated with properties that are not referenced by other groups //2.1) other groups under the current classification 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) attributes associated with these groups 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) remove these attributes from all attributes of the current classification; 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; }
4. Get the new association relationship
///product/attrgroup/attr/relation @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); }