src/main/java/cc/mrbird/febs/ai/controller/productCategory/AiProductCategoryController.java
@@ -6,6 +6,7 @@ import cc.mrbird.febs.common.controller.BaseController; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.entity.QueryRequest; import cc.mrbird.febs.mall.vo.AdminMallGoodsCategoryTreeVo; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; @@ -13,6 +14,7 @@ import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.util.List; import java.util.Map; /** @@ -73,4 +75,11 @@ return new FebsResponse().success().data(service.categoryTree()); } @GetMapping("categoryTree/parent") @ControllerEndpoint(exceptionMessage = "获取分类失败") public List<AiProductCategory> parent(){ return service.parent(); } } src/main/java/cc/mrbird/febs/ai/entity/AiProductCategory.java
@@ -1,8 +1,11 @@ package cc.mrbird.febs.ai.entity; import cc.mrbird.febs.common.entity.AiBaseEntity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.List; /** * AI产品类别 @@ -54,4 +57,8 @@ private Integer hotState; private Integer level; private String parentId; @TableField(exist = false) private String parentName; @TableField(exist = false) private List<AiProductCategory> child; } src/main/java/cc/mrbird/febs/ai/enums/ProductCategoryLevelEnum.java
New file @@ -0,0 +1,24 @@ package cc.mrbird.febs.ai.enums; import lombok.Getter; /** * @author wzy * @date 2021-09-26 **/ @Getter public enum ProductCategoryLevelEnum { LEVEL_TWO("二级菜单",2), LEVEL_ONE("一级菜单",1); private String name; private Integer level; ProductCategoryLevelEnum(String name,Integer level) { this.level = level; this.name = name; } } src/main/java/cc/mrbird/febs/ai/service/AiProductCategoryService.java
@@ -40,4 +40,6 @@ FebsResponse delete(String id); List<AiProductCategory> categoryTree(); List<AiProductCategory> parent(); } src/main/java/cc/mrbird/febs/ai/service/impl/AiProductCategoryServiceImpl.java
@@ -2,6 +2,7 @@ import cc.mrbird.febs.ai.entity.AiMemberRole; import cc.mrbird.febs.ai.entity.AiProductCategory; import cc.mrbird.febs.ai.enums.ProductCategoryLevelEnum; import cc.mrbird.febs.ai.mapper.AiProductCategoryMapper; import cc.mrbird.febs.ai.service.AiProductCategoryService; import cc.mrbird.febs.ai.util.UUID; @@ -9,6 +10,7 @@ import cc.mrbird.febs.common.entity.QueryRequest; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -20,6 +22,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; /** * AI产品类别 Service实现类 @@ -43,9 +46,42 @@ public List<AiProductCategory> getList() { LambdaQueryWrapper<AiProductCategory> query = Wrappers.lambdaQuery(AiProductCategory.class); query.ne(AiProductCategory::getState, 2); query.eq(AiProductCategory::getLevel, ProductCategoryLevelEnum.LEVEL_ONE.getLevel()); query.orderByDesc(AiProductCategory::getHotState); query.orderByAsc(AiProductCategory::getSort); List<AiProductCategory> aiProductCategories = aiProductCategoryMapper.selectList(query); if (CollUtil.isNotEmpty(aiProductCategories)){ Set<String> parentIds = aiProductCategories.stream().map(AiProductCategory::getId).collect(Collectors.toSet()); if (CollUtil.isNotEmpty(parentIds)){ List<AiProductCategory> aiProductCategoriesChild = aiProductCategoryMapper.selectList( Wrappers.lambdaQuery(AiProductCategory.class) .in(AiProductCategory::getParentId, parentIds) .ne(AiProductCategory::getState, 2) .eq(AiProductCategory::getLevel, ProductCategoryLevelEnum.LEVEL_TWO.getLevel()) .orderByAsc(AiProductCategory::getSort) ); //Stream流操作aiProductCategoriesChild,返回一个Map<ParentId,List<AiProductCategory>>,List<AiProductCategory>按照sort排序 Map<String, List<AiProductCategory>> resultMap = aiProductCategoriesChild.stream() .collect(Collectors.groupingBy( AiProductCategory::getParentId, Collectors.collectingAndThen( Collectors.toList(), list -> list.stream() .sorted(Comparator.comparing(AiProductCategory::getSort)) .collect(Collectors.toList()) ) )); if (CollUtil.isNotEmpty(resultMap)){ aiProductCategories.forEach(aiProductCategory -> { List<AiProductCategory> collect = resultMap.get(aiProductCategory.getId()); if (CollUtil.isNotEmpty(collect)){ aiProductCategory.setChild(collect); } }); } } } return aiProductCategories; } @@ -74,6 +110,25 @@ query.orderByDesc(AiProductCategory::getHotState); query.orderByAsc(AiProductCategory::getSort); Page<AiProductCategory> pages = aiProductCategoryMapper.selectPage(page, query); List<AiProductCategory> records = pages.getRecords(); if (CollUtil.isNotEmpty( records)){ //stream流获取全部的parentId Set<String> parentIds = records.stream().map(AiProductCategory::getParentId).collect(Collectors.toSet()); if (CollUtil.isNotEmpty(parentIds)){ List<AiProductCategory> aiProductCategories = aiProductCategoryMapper.selectList( Wrappers.lambdaUpdate(AiProductCategory.class) .in(AiProductCategory::getId, parentIds) ); Map<String, AiProductCategory> map = aiProductCategories.stream().collect( Collectors.toMap(AiProductCategory::getId, aiProductCategory -> aiProductCategory)); records.forEach(aiProductCategory -> { AiProductCategory orDefault = map.getOrDefault(aiProductCategory.getParentId(), null); if(ObjectUtil.isNotNull(orDefault)){ aiProductCategory.setParentName(orDefault.getName()); } }); } } return pages; } @@ -110,6 +165,8 @@ entity.setIconImg(dto.getIconImg()); entity.setSort(dto.getSort()); entity.setCreatedTime(new Date()); entity.setParentId(dto.getParentId()); entity.setLevel(StrUtil.isNotEmpty(dto.getParentId()) ? 2 : 1); this.save(entity); return new FebsResponse().success().message("操作成功"); } @@ -152,4 +209,13 @@ public List<AiProductCategory> categoryTree() { return this.getList() ; } @Override public List<AiProductCategory> parent() { LambdaQueryWrapper<AiProductCategory> query = Wrappers.lambdaQuery(AiProductCategory.class); query.select(AiProductCategory::getId,AiProductCategory::getName); query.eq(AiProductCategory::getLevel, 1); query.ne(AiProductCategory::getState, 2); return this.getBaseMapper().selectList(query); } } src/main/resources/templates/febs/views/modules/ai/productCategory/add.html
@@ -9,6 +9,17 @@ </ul> <div class="layui-tab-content"> <div class="layui-tab-item layui-show"> <div class="layui-row layui-col-space10 layui-form-item"> <div class="layui-col-lg6"> <label class="layui-form-label">父类:</label> <div class="layui-input-block"> <select name="parentId" class="category-add-productCategory"> <option value="">请选择</option> </select> </div> </div> </div> <div class="layui-row layui-col-space10 layui-form-item"> <div class="layui-col-lg6"> <label class="layui-form-label febs-form-item-require">名称:</label> @@ -151,6 +162,18 @@ } }); //(下拉框) $.get(ctx + 'admin/productCategory/categoryTree/parent', function (data) { for (var k in data) { $(".category-add-productCategory").append("<option value='" + data[k].id + "'>" + data[k].name + "</option>"); } layui.use('form', function () { var form = layui.form; form.render(); }); }); form.on('submit(productCategory-add-form-submit)', function (data) { $.ajax({ 'url':ctx + 'admin/productCategory/add', src/main/resources/templates/febs/views/modules/ai/productCategory/info.html
@@ -13,6 +13,16 @@ <div class="layui-tab-item layui-show"> <div class="layui-row layui-col-space10 layui-form-item"> <div class="layui-col-lg6"> <label class="layui-form-label">父类:</label> <div class="layui-input-block"> <select name="parentId" class="category-add-productCategory" id="category-add-productCategory-select"> <option value="">请选择</option> </select> </div> </div> </div> <div class="layui-row layui-col-space10 layui-form-item"> <div class="layui-col-lg6"> <label class="layui-form-label febs-form-item-require">名称:</label> <div class="layui-input-block"> <input type="text" name="name" lay-verify="required" @@ -161,7 +171,18 @@ } }); //(下拉框) $.get(ctx + 'admin/productCategory/categoryTree/parent', function (data) { for (var k in data) { $(".category-add-productCategory").append("<option value='" + data[k].id + "'>" + data[k].name + "</option>"); } layui.use('form', function () { var form = layui.form; $("#category-add-productCategory-select").val(aiProductCategory.parentId) form.render(); }); }); setTimeout(() => { initproductCategoryInfo(); src/main/resources/templates/febs/views/modules/ai/productCategory/list.html
@@ -242,7 +242,9 @@ {field: 'state', title: '状态', templet: '#productCategoryStateSwitch', minWidth: 130,align:'center'}, {field: 'sort', title: '排序', minWidth: 100,align:'center'}, {field: 'code', title: '编码', minWidth: 100,align:'center'}, {field: 'level', title: '级别', minWidth: 100,align:'center'}, {field: 'name', title: '名称', minWidth: 100,align:'center'}, {field: 'parentName', title: '父级名称', minWidth: 100,align:'center'}, {field: 'iconImg',title: '小图标', templet: function (d) { return '<a lay-event="seeImage">' +