package com.alatus.mall.product.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alatus.mall.product.entity.CategoryEntity;
import com.alatus.mall.product.service.CategoryService;
import com.alatus.common.utils.PageUtils;
import com.alatus.common.utils.R;
/**
* 商品三级分类
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 13:05:30
*/
@RestController
@RequestMapping("product/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 查出所有分类以及子分类,并以树形结构组装
*/
@RequestMapping("/list/tree")
public R listWithTree(){
List<CategoryEntity> entities = categoryService.listWithTree();
return R.ok().put("data", entities);
}
/**
* 列表
*/
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params){
PageUtils page = categoryService.queryPage(params);
return R.ok().put("page", page);
}
/**
* 信息
*/
@RequestMapping("/info/{catId}")
public R info(@PathVariable("catId") Long catId){
CategoryEntity category = categoryService.getById(catId);
return R.ok().put("category", category);
}
/**
* 保存
*/
@RequestMapping("/save")
public R save(@RequestBody CategoryEntity category){
categoryService.save(category);
return R.ok();
}
/**
* 批量修改
*/
@RequestMapping("/update/sort")
public R updateSort(@RequestBody CategoryEntity[] categories){
categoryService.updateBatchById(Arrays.asList(categories));
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@RequestBody CategoryEntity category){
categoryService.updateCascade(category);
return R.ok();
}
/**
* 删除
*/
// @RequestBody注解是为了获取请求体的内容,因为只有Post采有,所以必须是Post请求
// SpringMvc自动将我们请求体的数据Json转为对象
@RequestMapping("/delete")
public R delete(@RequestBody Long[] catIds){
// 检查当前删除的菜单是否被其他地方引用
categoryService.removeMenuByIds(Arrays.asList(catIds));
return R.ok();
}
}
package com.alatus.mall.product.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alatus.mall.product.entity.CategoryEntity;
import com.alatus.mall.product.service.CategoryService;
import com.alatus.common.utils.PageUtils;
import com.alatus.common.utils.R;
/**
* 商品三级分类
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 13:05:30
*/
@RestController
@RequestMapping("product/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 查出所有分类以及子分类,并以树形结构组装
*/
@RequestMapping("/list/tree")
public R listWithTree(){
List<CategoryEntity> entities = categoryService.listWithTree();
return R.ok().put("data", entities);
}
/**
* 列表
*/
@RequestMapping("/list")
public R list(@RequestParam Map<String, Object> params){
PageUtils page = categoryService.queryPage(params);
return R.ok().put("page", page);
}
/**
* 信息
*/
@RequestMapping("/info/{catId}")
public R info(@PathVariable("catId") Long catId){
CategoryEntity category = categoryService.getById(catId);
return R.ok().put("category", category);
}
/**
* 保存
*/
@RequestMapping("/save")
public R save(@RequestBody CategoryEntity category){
categoryService.save(category);
return R.ok();
}
/**
* 批量修改
*/
@RequestMapping("/update/sort")
public R updateSort(@RequestBody CategoryEntity[] categories){
categoryService.updateBatchById(Arrays.asList(categories));
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@RequestBody CategoryEntity category){
categoryService.updateCascade(category);
return R.ok();
}
/**
* 删除
*/
// @RequestBody注解是为了获取请求体的内容,因为只有Post采有,所以必须是Post请求
// SpringMvc自动将我们请求体的数据Json转为对象
@RequestMapping("/delete")
public R delete(@RequestBody Long[] catIds){
// 检查当前删除的菜单是否被其他地方引用
categoryService.removeMenuByIds(Arrays.asList(catIds));
return R.ok();
}
}
package com.alatus.mall.product.dao;
import com.alatus.mall.product.entity.CategoryEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 商品三级分类
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 13:05:30
*/
@Mapper
public interface CategoryDao extends BaseMapper<CategoryEntity> {
}
package com.alatus.mall.product.dao;
import com.alatus.mall.product.entity.CategoryEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 商品三级分类
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 13:05:30
*/
@Mapper
public interface CategoryDao extends BaseMapper<CategoryEntity> {
}
package com.alatus.mall.product.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
/**
* 商品三级分类
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 13:05:30
*/
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 分类id
*/
@TableId
private Long catId;
/**
* 分类名称
*/
private String name;
/**
* 父分类id
*/
private Long parentCid;
/**
* 层级
*/
private Integer catLevel;
/**
* 是否显示[0-不显示,1显示]
*/
@TableLogic(value = "1",delval = "0")
private Integer showStatus;
/**
* 排序
*/
private Integer sort;
/**
* 图标地址
*/
private String icon;
/**
* 计量单位
*/
private String productUnit;
/**
* 商品数量
*/
private Integer productCount;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false)
private List<CategoryEntity> children;
}
package com.alatus.mall.product.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
/**
* 商品三级分类
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 13:05:30
*/
@Data
@TableName("pms_category")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 分类id
*/
@TableId
private Long catId;
/**
* 分类名称
*/
private String name;
/**
* 父分类id
*/
private Long parentCid;
/**
* 层级
*/
private Integer catLevel;
/**
* 是否显示[0-不显示,1显示]
*/
@TableLogic(value = "1",delval = "0")
private Integer showStatus;
/**
* 排序
*/
private Integer sort;
/**
* 图标地址
*/
private String icon;
/**
* 计量单位
*/
private String productUnit;
/**
* 商品数量
*/
private Integer productCount;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@TableField(exist = false)
private List<CategoryEntity> children;
}
package com.alatus.mall.product.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.alatus.common.utils.PageUtils;
import com.alatus.mall.product.entity.CategoryEntity;
import java.util.List;
import java.util.Map;
/**
* 商品三级分类
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 13:05:30
*/
public interface CategoryService extends IService<CategoryEntity> {
PageUtils queryPage(Map<String, Object> params);
List<CategoryEntity> listWithTree();
void removeMenuByIds(List<Long> list);
// 找到CatelogId的完整路径
Long[] findCatelogPath(Long catelogId);
void updateCascade(CategoryEntity category);
}
package com.alatus.mall.product.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.alatus.common.utils.PageUtils;
import com.alatus.mall.product.entity.CategoryEntity;
import java.util.List;
import java.util.Map;
/**
* 商品三级分类
*
* @author alatus
* @email 1571345941@qq.com
* @date 2024-03-12 13:05:30
*/
public interface CategoryService extends IService<CategoryEntity> {
PageUtils queryPage(Map<String, Object> params);
List<CategoryEntity> listWithTree();
void removeMenuByIds(List<Long> list);
// 找到CatelogId的完整路径
Long[] findCatelogPath(Long catelogId);
void updateCascade(CategoryEntity category);
}
package com.alatus.mall.product.service.impl;
import com.alatus.mall.product.service.CategoryBrandRelationService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
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.alatus.common.utils.PageUtils;
import com.alatus.common.utils.Query;
import com.alatus.mall.product.dao.CategoryDao;
import com.alatus.mall.product.entity.CategoryEntity;
import com.alatus.mall.product.service.CategoryService;
import org.springframework.transaction.annotation.Transactional;
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
@Autowired
private CategoryBrandRelationService categoryBrandRelationService;
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<CategoryEntity> page = this.page(
new Query<CategoryEntity>().getPage(params),
new QueryWrapper<CategoryEntity>()
);
return new PageUtils(page);
}
@Override
public List<CategoryEntity> listWithTree() {
// 查出所有分类
List<CategoryEntity> entities = baseMapper.selectList(null);
// 组装父子的树形结构
// 找到一级分类
List<CategoryEntity> levelMenuOne = entities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() == 0
).map((menu) -> {
menu.setChildren(getChildren(menu,entities));
return menu;
}).sorted((menu1,menu2) -> {
return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
}).collect(Collectors.toList());
return levelMenuOne;
}
@Override
public void removeMenuByIds(List<Long> list) {
// 检查当前删除的菜单,是否被别的地方引用
baseMapper.deleteBatchIds(list);
}
@Override
public Long[] findCatelogPath(Long catelogId) {
List<Long> paths = new ArrayList<>();
List<Long> parentPath = findParent(catelogId, paths);
Collections.reverse(parentPath);
return (Long[])parentPath.toArray(new Long[parentPath.size()]);
}
// 级联更新所有数据
@Override
@Transactional
public void updateCascade(CategoryEntity category) {
this.updateById(category);
categoryBrandRelationService.updateCategory(category.getCatId(),category.getName());
}
private List<Long> findParent(Long catelogId,List<Long> paths){
// 查出当前分类的ID
// 收集当前节点ID
paths.add(catelogId);
CategoryEntity id = this.getById(catelogId);
if(id.getParentCid() != 0){
// 递归查找,每次都从父节点获取
findParent(id.getParentCid(),paths);
}
return paths;
}
// 递归查找所有菜单的子菜单
private List<CategoryEntity> getChildren(CategoryEntity root,List<CategoryEntity> all){
List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
return categoryEntity.getParentCid() == root.getCatId();
}).map(categoryEntity -> {
categoryEntity.setChildren(getChildren(categoryEntity,all));
return categoryEntity;
}).sorted((menu1,menu2) ->{
return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
}).collect(Collectors.toList());
return children;
}
}
package com.alatus.mall.product.service.impl;
import com.alatus.mall.product.service.CategoryBrandRelationService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
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.alatus.common.utils.PageUtils;
import com.alatus.common.utils.Query;
import com.alatus.mall.product.dao.CategoryDao;
import com.alatus.mall.product.entity.CategoryEntity;
import com.alatus.mall.product.service.CategoryService;
import org.springframework.transaction.annotation.Transactional;
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
@Autowired
private CategoryBrandRelationService categoryBrandRelationService;
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<CategoryEntity> page = this.page(
new Query<CategoryEntity>().getPage(params),
new QueryWrapper<CategoryEntity>()
);
return new PageUtils(page);
}
@Override
public List<CategoryEntity> listWithTree() {
// 查出所有分类
List<CategoryEntity> entities = baseMapper.selectList(null);
// 组装父子的树形结构
// 找到一级分类
List<CategoryEntity> levelMenuOne = entities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() == 0
).map((menu) -> {
menu.setChildren(getChildren(menu,entities));
return menu;
}).sorted((menu1,menu2) -> {
return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
}).collect(Collectors.toList());
return levelMenuOne;
}
@Override
public void removeMenuByIds(List<Long> list) {
// 检查当前删除的菜单,是否被别的地方引用
baseMapper.deleteBatchIds(list);
}
@Override
public Long[] findCatelogPath(Long catelogId) {
List<Long> paths = new ArrayList<>();
List<Long> parentPath = findParent(catelogId, paths);
Collections.reverse(parentPath);
return (Long[])parentPath.toArray(new Long[parentPath.size()]);
}
// 级联更新所有数据
@Override
@Transactional
public void updateCascade(CategoryEntity category) {
this.updateById(category);
categoryBrandRelationService.updateCategory(category.getCatId(),category.getName());
}
private List<Long> findParent(Long catelogId,List<Long> paths){
// 查出当前分类的ID
// 收集当前节点ID
paths.add(catelogId);
CategoryEntity id = this.getById(catelogId);
if(id.getParentCid() != 0){
// 递归查找,每次都从父节点获取
findParent(id.getParentCid(),paths);
}
return paths;
}
// 递归查找所有菜单的子菜单
private List<CategoryEntity> getChildren(CategoryEntity root,List<CategoryEntity> all){
List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
return categoryEntity.getParentCid() == root.getCatId();
}).map(categoryEntity -> {
categoryEntity.setChildren(getChildren(categoryEntity,all));
return categoryEntity;
}).sorted((menu1,menu2) ->{
return (menu1.getSort()==null?0:menu1.getSort()) - (menu2.getSort()==null?0:menu2.getSort());
}).collect(Collectors.toList());
return children;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.alatus.mall.product.dao.CategoryDao">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.alatus.mall.product.entity.CategoryEntity" id="categoryMap">
<result property="catId" column="cat_id"/>
<result property="name" column="name"/>
<result property="parentCid" column="parent_cid"/>
<result property="catLevel" column="cat_level"/>
<result property="showStatus" column="show_status"/>
<result property="sort" column="sort"/>
<result property="icon" column="icon"/>
<result property="productUnit" column="product_unit"/>
<result property="productCount" column="product_count"/>
</resultMap>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.alatus.mall.product.dao.CategoryDao">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.alatus.mall.product.entity.CategoryEntity" id="categoryMap">
<result property="catId" column="cat_id"/>
<result property="name" column="name"/>
<result property="parentCid" column="parent_cid"/>
<result property="catLevel" column="cat_level"/>
<result property="showStatus" column="show_status"/>
<result property="sort" column="sort"/>
<result property="icon" column="icon"/>
<result property="productUnit" column="product_unit"/>
<result property="productCount" column="product_count"/>
</resultMap>
</mapper>