SpringBoot+Mybatis实现三级分类联动

您所在的位置:网站首页 java实现二级联动 SpringBoot+Mybatis实现三级分类联动

SpringBoot+Mybatis实现三级分类联动

2024-07-13 21:03| 来源: 网络整理| 查看: 265

一、后台管理系统表格分页形式的分类显示

先来看实现的效果。 在这里插入图片描述这是所有商品的一级分类,选中一个一级分类后(如图中的“家电 数码 手机”)点击“下级分类管理”,即跳转至该分类的二级分类,如下图。 在这里插入图片描述再选择二级分类中的“家电”后,点击“下级分类管理”,即跳转至该二级分类下的三级分类,如下图。 在这里插入图片描述 所有的分类都是记录在同一张表内,表内主要字段如下。

属性名说明category_id自增id,用于记录每个分类的编号category_level表示该分类属于几级分类parent_id表示该分类的上级分类的id,如果是一级分类,则为0category_name分类名称category_rank分类排序值,值越高越靠前显示

另外在前后端传值的时候有三个关键的参数:

categoryLevel, 用来表格该分类的等级parentId,用来表格该分类的上级分类的id,一级分类则为0backParentId,用来表示三级分类的parentId所对应的二级分类的一级分类

现在开始上代码。 初试列表显示的是所有一级分类,因此这里三个参数分别为:categoryLevel=1,parentId=0,backParentId=0;url为: admin/categories?parentId=0&categoryLevel=1&backParentId=0 二级列表和三级列表的参数由前端获取到后传给后端。

NewBeeMallGoodsCategoryController.java @Resource private NewBeeMallCategoryService newBeeMallCategoryService; /** * 列表显示 */ @RequestMapping(value = "/categories/list" ,method = RequestMethod.GET) @ResponseBody public Result list(@RequestParam Map params){ if (StringUtils.isEmpty(params.get("page")) || StringUtils.isEmpty(params.get("limit"))){ return ResultGenerator.genFailResult("参数异常"); } PageQueryUtil pageQueryUtil = new PageQueryUtil(params); return ResultGenerator.genSuccessResult(newBeeMallCategoryService.getCategoriesPage(pageQueryUtil)); }

(categoryLevel=1,parentId=0封装在params中)

NewBeeMallCategoryService.java /** * 管理后台分页显示 * @param pageQueryUtil * @return */ PageResult getCategoriesPage(PageQueryUtil pageQueryUtil); NewBeeMallCategoryServiceImpl.java @Autowired private GoodsCategoryMapper goodsCategoryMapper; @Override public PageResult getCategoriesPage(PageQueryUtil pageQueryUtil) { List goodsCategories = goodsCategoryMapper.findGoodsCategoryList(pageQueryUtil); int total = goodsCategoryMapper.getTotalGoodsCategories(pageQueryUtil); PageResult pageResult = new PageResult(goodsCategories,total,pageQueryUtil.getLimit(),pageQueryUtil.getPage()); return pageResult; } GoodsCategoryMapper.java /** * 后台获取分类列表 * @param pageQueryUtil * @return */ List findGoodsCategoryList(PageQueryUtil pageQueryUtil); /** * 后台获取分类总数 * @param pageQueryUtil * @return */ int getTotalGoodsCategories(PageQueryUtil pageQueryUtil); GoodsCategoryMapper.xml category_id, category_level, parent_id, category_name, category_rank, is_deleted, create_time, create_user, update_time, update_user select from tb_newbee_mall_goods_category and category_level = #{categoryLevel} and parent_id = #{parentId} and is_deleted = 0 order by category_rank desc limit #{start},#{limit} select count(*) from tb_newbee_mall_goods_category and category_level = #{categoryLevel} and parent_id = #{parentId} and is_deleted = 0 二、添加商品页面的下拉菜单式的三级联动

实际效果如图所示。 在这里插入图片描述在这里插入图片描述 在这里插入图片描述第一个下拉菜单默认显示排序值最高的一级分类。第二个下拉菜单显示的是该一级分类下的第一个二级分类。第三个下拉菜单显示的是该二级分类下的第一个三级分类。若没有内容则显示空白。这里有三种情况,分别是:

(1)打开页面后的默认显示

一打开这个页面默认显示的是第一个一级分类,和其所属的第一个二级分类以及该二级分类下的第一个三级分类,即:“家电 数码 手机” -->“家电” --> “生活电器”。

NewBeeMallGoodsController.java @Resource private NewBeeMallCategoryService newBeeMallCategoryService; @GetMapping("/goods/edit") public String edit(HttpServletRequest request){ request.setAttribute("path", "edit"); //查询所有的一级分类 List firstLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(0L), NewBeeMallCategoryLevelEnum.LEVEL_ONE.getLevel()); if (!CollectionUtils.isEmpty(firstLevelCategories)){ //查询一级分类列表中第一个实体的所有二级分类 List secondLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(firstLevelCategories.get(0).getCategoryId()), NewBeeMallCategoryLevelEnum.LEVEL_TWO.getLevel()); if (!CollectionUtils.isEmpty(secondLevelCategories)){ //查询二级分类列表中第一个实体的所有三级分类 List thirdLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(secondLevelCategories.get(0).getCategoryId()),NewBeeMallCategoryLevelEnum.LEVEL_THREE.getLevel()); request.setAttribute("firstLevelCategories",firstLevelCategories); request.setAttribute("secondLevelCategories",secondLevelCategories); request.setAttribute("thirdLevelCategories",thirdLevelCategories); request.setAttribute("path","goods-edit"); return "admin/newbee_mall_goods_edit"; } } return "error/error_5xx"; } NewBeeMallCategoryService.java /** * 根据parentId和level获取分类列表 * @param parentIds * @param categoryLevel * @return */ List selectByLevelAndParentIdsAndNumber(List parentIds, int categoryLevel); NewBeeMallCategoryServiceImpl.java @Autowired private GoodsCategoryMapper goodsCategoryMapper; @Override public List selectByLevelAndParentIdsAndNumber(List parentIds, int categoryLevel){ return goodsCategoryMapper.selectByLevelAndParentIdsAndNumber(parentIds,categoryLevel,0);//0代表查询所有 } GoodsCategoryMapper.java List selectByLevelAndParentIdsAndNumber(@Param("parentIds") List parentIds,@Param("categoryLevel") int categoryLevel,@Param("number") int number); GoodsCategoryMapper.xml select from tb_newbee_mall_goods_category where parent_id in #{parentId,jdbcType=BIGINT} and category_level = #{categoryLevel,jdbcType=TINYINT} and is_deleted = 0 order by category_rank desc limit #{number} (2)修改商品信息页,已知商品id

这种情况下是用户在商品列表选择了相应的商品后,点击编辑按钮,希望修改这个商品的基本信息(如,分类、库存、售价等),这个时候页面跳转到与前面的截图相同的页面,区别就是这个时候的三级菜单会自动显示当前该商品所在的三级分类,即数据回显。如下图所示,我选中了其中一个商品(如小米某型号手机),返回的页面是这样的。 在这里插入图片描述

NewBeeMallGoodsController.java @Resource private NewBeeMallGoodsService newBeeMallGoodsService; @GetMapping("/goods/edit/{goodsId}") public String edit(HttpServletRequest request,@PathVariable("goodsId") Long goodsId){ request.setAttribute("path","edit"); NewBeeMallGoods newBeeMallGoods = newBeeMallGoodsService.getNewBeeMallGoodsById(goodsId); if(newBeeMallGoods == null){ return "error/error_400"; } if(newBeeMallGoods.getGoodsCategoryId() > 0){ if (newBeeMallGoods.getGoodsCategoryId() != null || newBeeMallGoods.getGoodsCategoryId() > 0){ //有分类字段则查询相关分类数据返回给前端以供分类的三级联动显示 GoodsCategory currentGoodsCategory = newBeeMallCategoryService.getGoodsCategoryById(newBeeMallGoods.getGoodsCategoryId()); //商品表中存储的分类id字段为三级分类的id,不为三级分类则是错误数据 if (currentGoodsCategory != null && currentGoodsCategory.getCategoryLevel() == NewBeeMallCategoryLevelEnum.LEVEL_THREE.getLevel()){ //查询所有的一级分类 List firstLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(0L),NewBeeMallCategoryLevelEnum.LEVEL_ONE.getLevel()); //根据parentId查询当前parentId下所有的三级分类 List thirdLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(currentGoodsCategory.getParentId()),NewBeeMallCategoryLevelEnum.LEVEL_THREE.getLevel()); //查询当前三级分类的父级二级分类 GoodsCategory secondCategory = newBeeMallCategoryService.getGoodsCategoryById(currentGoodsCategory.getParentId()); if(secondCategory != null){ //根据parentId查询当前parentId下所有的二级分类 List secondLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(secondCategory.getParentId()),NewBeeMallCategoryLevelEnum.LEVEL_TWO.getLevel()); //查询当前二级分类的父级一级分类 GoodsCategory firstCategory = newBeeMallCategoryService.getGoodsCategoryById(secondCategory.getParentId()); if (firstCategory != null){ //所有分类数据都得到之后放到request对象中供前端读取 request.setAttribute("firstLevelCategories", firstLevelCategories); request.setAttribute("secondLevelCategories", secondLevelCategories); request.setAttribute("thirdLevelCategories", thirdLevelCategories); request.setAttribute("firstLevelCategoryId", firstCategory.getCategoryId()); request.setAttribute("secondLevelCategoryId", secondCategory.getCategoryId()); request.setAttribute("thirdLevelCategoryId", currentGoodsCategory.getCategoryId()); } } } } } if (newBeeMallGoods.getGoodsCategoryId() == 0) { //查询所有的一级分类 List firstLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(0L), NewBeeMallCategoryLevelEnum.LEVEL_ONE.getLevel()); if (!CollectionUtils.isEmpty(firstLevelCategories)) { //查询一级分类列表中第一个实体的所有二级分类 List secondLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(firstLevelCategories.get(0).getCategoryId()), NewBeeMallCategoryLevelEnum.LEVEL_TWO.getLevel()); if (!CollectionUtils.isEmpty(secondLevelCategories)) { //查询二级分类列表中第一个实体的所有三级分类 List thirdLevelCategories = newBeeMallCategoryService.selectByLevelAndParentIdsAndNumber(Collections.singletonList(secondLevelCategories.get(0).getCategoryId()), NewBeeMallCategoryLevelEnum.LEVEL_THREE.getLevel()); request.setAttribute("firstLevelCategories", firstLevelCategories); request.setAttribute("secondLevelCategories", secondLevelCategories); request.setAttribute("thirdLevelCategories", thirdLevelCategories); } } } request.setAttribute("goods", newBeeMallGoods); request.setAttribute("path", "goods-edit"); return "admin/newbee_mall_goods_edit"; } NewBeeMallGoodsService.java /** * 根据id获取商品详情 * @param id * @return */ NewBeeMallGoods getNewBeeMallGoodsById(Long id); NewBeeMallGoodsServiceImpl.java @Autowired private NewBeeMallGoodsMapper goodsMapper; @Override public NewBeeMallGoods getNewBeeMallGoodsById(Long id) { return goodsMapper.selectByPrimaryKey(id); } NewBeeMallGoodsMapper.java /** * 根据id获取商品 * @param goodsId * @return */ NewBeeMallGoods selectByPrimaryKey(Long goodsId); NewBeeMallGoodsMapper.xml goods_id, goods_name, goods_intro,goods_category_id, goods_cover_img, goods_carousel, original_price, selling_price, stock_num, tag, goods_sell_status, create_user, create_time, update_user, update_time goods_detail_content select , from tb_newbee_mall_goods_info where goods_id = #{goodsId,jdbcType=BIGINT} (3)手动选择更改分类

当我们手动选择了一个一级分类后,二级分类的下拉菜单会自动修改为当前选择的那个一级分类下的第一个二级分类,三级分类的下拉菜单会自动修改为当前第一个二级分类下的第一个三级分类,如果没有相应的下属分类则不显示。当自己手动选择了一个二级分类后,三级分类的下拉菜单会自动修改为当前选择的二级分类下的第一个三级分类。

NewBeeMallGoodsCategoryController.java @Resource private NewBeeMallCategoryService newBeeMallCategoryService; /** * 添加/修改商品信息页的列表显示 */ @RequestMapping(value = "/categories/listForSelect",method = RequestMethod.GET) @ResponseBody public Result listForSelect(@RequestParam("categoryId") Long categoryId){ if (categoryId == null || categoryId category_id, category_level, parent_id, category_name, category_rank, is_deleted, create_time, create_user, update_time, update_user select from tb_newbee_mall_goods_category where category_id = #{categoryId,jdbcType=BIGINT} and is_deleted=0 select from tb_newbee_mall_goods_category where parent_id in #{parentId,jdbcType=BIGINT} and category_level = #{categoryLevel,jdbcType=TINYINT} and is_deleted = 0 order by category_rank desc limit #{number} 三、商城首页三级分类显示

后台管理系统配置好了分类之后,就是用来在前台商城首页显示。首页如图所示。 在这里插入图片描述

IndexController.java @Resource private NewBeeMallCategoryService newBeeMallCategoryService; @GetMapping({"/index", "/", "/index.html"}) public String indexPage(HttpServletRequest request){ List categories = newBeeMallCategoryService.getCategoriesForIndex(); if (CollectionUtils.isEmpty(categories)){ return "error/error_5xx"; } request.setAttribute("categories",categories);//分类数据 return "mall/index"; } NewBeeMallCategoryService.java /** * 商城首页返回分类数据 * @return */ List getCategoriesForIndex(); NewBeeMallCategoryServiceImpl.java @Autowired private GoodsCategoryMapper goodsCategoryMapper; @Override public List getCategoriesForIndex() { List newBeeMallIndexCategoryVOS = new ArrayList(); //获取一级分类的固定数量的数据 List firstLevelCategories = goodsCategoryMapper.selectByLevelAndParentIdsAndNumber(Collections.singletonList(0L), NewBeeMallCategoryLevelEnum.LEVEL_ONE.getLevel(), Constants.INDEX_CATEGORY_NUMBER); if (!CollectionUtils.isEmpty(firstLevelCategories)){ List firstLevelCategoryIds = firstLevelCategories.stream().map(GoodsCategory::getCategoryId).collect(Collectors.toList()); //获取二级分类的数据 List secondLevelCategories = goodsCategoryMapper.selectByLevelAndParentIdsAndNumber(firstLevelCategoryIds,NewBeeMallCategoryLevelEnum.LEVEL_TWO.getLevel(), 0); if (!CollectionUtils.isEmpty(secondLevelCategories)){ List secondLevelCategoryIds = secondLevelCategories.stream().map(GoodsCategory::getCategoryId).collect(Collectors.toList()); //获取三级分类的数据 List thirdLevelCategories = goodsCategoryMapper.selectByLevelAndParentIdsAndNumber(secondLevelCategoryIds,NewBeeMallCategoryLevelEnum.LEVEL_THREE.getLevel(),0); if (!CollectionUtils.isEmpty(thirdLevelCategories)){ //根据parentId 将 thirdLevelCategories分组 Map thirdLevelCategoryMap = thirdLevelCategories.stream().collect(groupingBy(GoodsCategory::getParentId)); List secondLevelCategoryVOS = new ArrayList(); //处理二级分类 for (GoodsCategory secondLevelCategory : secondLevelCategories){ SecondLevelCategoryVO secondLevelCategoryVO = new SecondLevelCategoryVO(); BeanUtil.copyProperties(secondLevelCategory,secondLevelCategoryVO); //如果该二级分类下有数据则放入 secondLevelCategoryVOS 对象中 if (thirdLevelCategoryMap.containsKey(secondLevelCategory.getCategoryId())){ //根据二级分类的id取出thirdLevelCategoryMap分组中的三级分类list List tempGoodsCategories = thirdLevelCategoryMap.get(secondLevelCategory.getCategoryId()); secondLevelCategoryVO.setThirdLevelCategoryVOS((BeanUtil.copyList(tempGoodsCategories, ThirdLevelCategoryVO.class))); secondLevelCategoryVOS.add(secondLevelCategoryVO); } } //处理一级分类 if (!CollectionUtils.isEmpty(secondLevelCategoryVOS)){ //根据parentId将 thirdLevelCategories分组 Map secondLevelCategoryVOMap = secondLevelCategoryVOS.stream().collect(groupingBy(SecondLevelCategoryVO::getParentId)); for (GoodsCategory firstCategory : firstLevelCategories){ NewBeeMallIndexCategoryVO newBeeMallIndexCategoryVO = new NewBeeMallIndexCategoryVO(); BeanUtil.copyProperties(firstCategory,newBeeMallIndexCategoryVO); //如果该一级分类下有数据则放入 newBeeMallIndexCategoryVOS 对象中 if (secondLevelCategoryVOMap.containsKey(firstCategory.getCategoryId())){ //根据该一级分类的id取出secondLevelCategoryVOMap分组中的二级分类list List tempGoodsCategories = secondLevelCategoryVOMap.get(firstCategory.getCategoryId()); newBeeMallIndexCategoryVO.setSecondLevelCategoryVOS(tempGoodsCategories); newBeeMallIndexCategoryVOS.add(newBeeMallIndexCategoryVO); } } } } } return newBeeMallIndexCategoryVOS; }else { return null; } } GoodsCategoryMapper.java category_id, category_level, parent_id, category_name, category_rank, is_deleted, create_time, create_user, update_time, update_user List selectByLevelAndParentIdsAndNumber(@Param("parentIds") List parentIds,@Param("categoryLevel") int categoryLevel,@Param("number") int number); GoodsCategoryMapper.xml select from tb_newbee_mall_goods_category where parent_id in #{parentId,jdbcType=BIGINT} and category_level = #{categoryLevel,jdbcType=TINYINT} and is_deleted = 0 order by category_rank desc limit #{number}

后端代码主要就是这些,前端表格插件使用jqgrid,数据交互主要使用thymeleaf模板引擎,因为主要想学习一下后端的知识,所以前端的代码就不贴上来了。(以上所有代码非本人原创,都是从“新蜂商城”这个开源项目上复制下来,仅做学习记录使用。)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3