mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 22:57:17 +08:00 
			
		
		
		
	重构:🔥 重构查询树列表相关 API,并抽取到后端 CRUD 公共组件中
1.基于 Hutool TreeUtil 重构查询树列表相关 API 2.抽取查询树列表 API 到后端 CRUD 公共组件中,大大简化部门管理和菜单管理部分代码
This commit is contained in:
		| @@ -51,6 +51,10 @@ public @interface CrudRequestMapping { | |||||||
|          * 分页 |          * 分页 | ||||||
|          */ |          */ | ||||||
|         PAGE, |         PAGE, | ||||||
|  |         /** | ||||||
|  |          * 树列表 | ||||||
|  |          */ | ||||||
|  |         TREE, | ||||||
|         /** |         /** | ||||||
|          * 列表 |          * 列表 | ||||||
|          */ |          */ | ||||||
|   | |||||||
| @@ -0,0 +1,74 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  |  * you may not use this file except in compliance with the License. | ||||||
|  |  * You may obtain a copy of the License at | ||||||
|  |  * | ||||||
|  |  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  |  * See the License for the specific language governing permissions and | ||||||
|  |  * limitations under the License. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | package top.charles7c.cnadmin.common.annotation; | ||||||
|  |  | ||||||
|  | import java.lang.annotation.*; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 树结构字段 | ||||||
|  |  * | ||||||
|  |  * @see cn.hutool.core.lang.tree.TreeNodeConfig | ||||||
|  |  * @author Charles7c | ||||||
|  |  * @since 2023/2/26 23:50 | ||||||
|  |  */ | ||||||
|  | @Target(ElementType.TYPE) | ||||||
|  | @Retention(RetentionPolicy.RUNTIME) | ||||||
|  | @Documented | ||||||
|  | public @interface TreeField { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * ID 字段名 | ||||||
|  |      * | ||||||
|  |      * @return ID 字段名 | ||||||
|  |      */ | ||||||
|  |     String value() default "key"; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 父 ID 字段名 | ||||||
|  |      * | ||||||
|  |      * @return 父 ID 字段名 | ||||||
|  |      */ | ||||||
|  |     String parentIdKey() default "parentId"; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 名称字段名 | ||||||
|  |      * | ||||||
|  |      * @return 名称字段名 | ||||||
|  |      */ | ||||||
|  |     String nameKey() default "title"; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 排序字段名 | ||||||
|  |      * | ||||||
|  |      * @return 排序字段名 | ||||||
|  |      */ | ||||||
|  |     String weightKey() default "sort"; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 子列表字段名 | ||||||
|  |      * | ||||||
|  |      * @return 子列表字段名 | ||||||
|  |      */ | ||||||
|  |     String childrenKey() default "children"; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 递归深度(< 0 不限制) | ||||||
|  |      * | ||||||
|  |      * @return 递归深度 | ||||||
|  |      */ | ||||||
|  |     int deep() default -1; | ||||||
|  | } | ||||||
| @@ -30,6 +30,8 @@ import org.springframework.beans.factory.annotation.Autowired; | |||||||
| import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||||
| import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.lang.tree.Tree; | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.model.query.PageQuery; | import top.charles7c.cnadmin.common.model.query.PageQuery; | ||||||
| import top.charles7c.cnadmin.common.model.query.SortQuery; | import top.charles7c.cnadmin.common.model.query.SortQuery; | ||||||
| import top.charles7c.cnadmin.common.model.vo.PageDataVO; | import top.charles7c.cnadmin.common.model.vo.PageDataVO; | ||||||
| @@ -74,6 +76,23 @@ public abstract class BaseController<S extends BaseService<V, D, Q, C>, V, D, Q, | |||||||
|         return R.ok(pageDataVO); |         return R.ok(pageDataVO); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 查询树列表 | ||||||
|  |      * | ||||||
|  |      * @param query | ||||||
|  |      *            查询条件 | ||||||
|  |      * @param sortQuery | ||||||
|  |      *            排序查询条件 | ||||||
|  |      * @return 树列表信息 | ||||||
|  |      */ | ||||||
|  |     @Operation(summary = "查询树列表") | ||||||
|  |     @ResponseBody | ||||||
|  |     @GetMapping("/tree") | ||||||
|  |     protected R<List<Tree<Long>>> tree(@Validated Q query, @Validated SortQuery sortQuery) { | ||||||
|  |         List<Tree<Long>> list = baseService.tree(query, sortQuery, false); | ||||||
|  |         return R.ok(list); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 查询列表 |      * 查询列表 | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -20,6 +20,8 @@ import java.util.List; | |||||||
|  |  | ||||||
| import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.lang.tree.Tree; | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.model.query.PageQuery; | import top.charles7c.cnadmin.common.model.query.PageQuery; | ||||||
| import top.charles7c.cnadmin.common.model.query.SortQuery; | import top.charles7c.cnadmin.common.model.query.SortQuery; | ||||||
| import top.charles7c.cnadmin.common.model.vo.PageDataVO; | import top.charles7c.cnadmin.common.model.vo.PageDataVO; | ||||||
| @@ -51,6 +53,19 @@ public interface BaseService<V, D, Q, C extends BaseRequest> { | |||||||
|      */ |      */ | ||||||
|     PageDataVO<V> page(Q query, PageQuery pageQuery); |     PageDataVO<V> page(Q query, PageQuery pageQuery); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 查询树列表 | ||||||
|  |      * | ||||||
|  |      * @param query | ||||||
|  |      *            查询条件 | ||||||
|  |      * @param sortQuery | ||||||
|  |      *            排序查询条件 | ||||||
|  |      * @param isSimple | ||||||
|  |      *            是否为简单树结构(不包含基本树结构之外的扩展字段) | ||||||
|  |      * @return 树列表信息 | ||||||
|  |      */ | ||||||
|  |     List<Tree<Long>> tree(Q query, SortQuery sortQuery, boolean isSimple); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 查询列表 |      * 查询列表 | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -16,8 +16,11 @@ | |||||||
|  |  | ||||||
| package top.charles7c.cnadmin.common.base; | package top.charles7c.cnadmin.common.base; | ||||||
|  |  | ||||||
|  | import java.lang.reflect.Field; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
| import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||||
|  |  | ||||||
| @@ -41,15 +44,21 @@ import cn.hutool.core.bean.BeanUtil; | |||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.hutool.core.convert.Convert; | import cn.hutool.core.convert.Convert; | ||||||
| import cn.hutool.core.lang.Opt; | import cn.hutool.core.lang.Opt; | ||||||
|  | import cn.hutool.core.lang.tree.Tree; | ||||||
|  | import cn.hutool.core.lang.tree.TreeNodeConfig; | ||||||
|  | import cn.hutool.core.util.ReflectUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.hutool.extra.spring.SpringUtil; | import cn.hutool.extra.spring.SpringUtil; | ||||||
|  |  | ||||||
|  | import top.charles7c.cnadmin.common.annotation.TreeField; | ||||||
| import top.charles7c.cnadmin.common.model.query.PageQuery; | import top.charles7c.cnadmin.common.model.query.PageQuery; | ||||||
| import top.charles7c.cnadmin.common.model.query.SortQuery; | import top.charles7c.cnadmin.common.model.query.SortQuery; | ||||||
| import top.charles7c.cnadmin.common.model.vo.PageDataVO; | import top.charles7c.cnadmin.common.model.vo.PageDataVO; | ||||||
| import top.charles7c.cnadmin.common.service.CommonUserService; | import top.charles7c.cnadmin.common.service.CommonUserService; | ||||||
| import top.charles7c.cnadmin.common.util.ExcelUtils; | import top.charles7c.cnadmin.common.util.ExcelUtils; | ||||||
| import top.charles7c.cnadmin.common.util.ExceptionUtils; | import top.charles7c.cnadmin.common.util.ExceptionUtils; | ||||||
|  | import top.charles7c.cnadmin.common.util.ReflectUtils; | ||||||
|  | import top.charles7c.cnadmin.common.util.TreeUtils; | ||||||
| import top.charles7c.cnadmin.common.util.helper.QueryHelper; | import top.charles7c.cnadmin.common.util.helper.QueryHelper; | ||||||
| import top.charles7c.cnadmin.common.util.validate.CheckUtils; | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
|  |  | ||||||
| @@ -90,6 +99,40 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T, V, D, Q, C ext | |||||||
|         return pageDataVO; |         return pageDataVO; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public List<Tree<Long>> tree(Q query, SortQuery sortQuery, boolean isSimple) { | ||||||
|  |         List<V> list = this.list(query, sortQuery); | ||||||
|  |         if (CollUtil.isEmpty(list)) { | ||||||
|  |             return Collections.emptyList(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 如果构建简单树结构,则不包含基本树结构之外的扩展字段 | ||||||
|  |         TreeNodeConfig treeNodeConfig = TreeUtils.DEFAULT_CONFIG; | ||||||
|  |         TreeField treeField = voClass.getDeclaredAnnotation(TreeField.class); | ||||||
|  |         if (!isSimple) { | ||||||
|  |             // 根据 @TreeField 配置生成树结构配置 | ||||||
|  |             treeNodeConfig = TreeUtils.genTreeNodeConfig(treeField); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 构建树 | ||||||
|  |         return TreeUtils.build(list, treeNodeConfig, (node, tree) -> { | ||||||
|  |             // 转换器 | ||||||
|  |             tree.setId(ReflectUtil.invoke(node, StrUtil.genGetter(treeField.value()))); | ||||||
|  |             tree.setParentId(ReflectUtil.invoke(node, StrUtil.genGetter(treeField.parentIdKey()))); | ||||||
|  |             tree.setName(ReflectUtil.invoke(node, StrUtil.genGetter(treeField.nameKey()))); | ||||||
|  |             tree.setWeight(ReflectUtil.invoke(node, StrUtil.genGetter(treeField.weightKey()))); | ||||||
|  |             if (!isSimple) { | ||||||
|  |                 Field[] fieldArr = ReflectUtils.getNonStaticFields(voClass); | ||||||
|  |                 List<Field> fieldList = Arrays.stream(fieldArr) | ||||||
|  |                     .filter(f -> !StrUtil.containsAnyIgnoreCase(f.getName(), treeField.value(), treeField.parentIdKey(), | ||||||
|  |                         treeField.nameKey(), treeField.weightKey(), treeField.childrenKey())) | ||||||
|  |                     .collect(Collectors.toList()); | ||||||
|  |                 fieldList | ||||||
|  |                     .forEach(f -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, StrUtil.genGetter(f.getName())))); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public List<V> list(Q query, SortQuery sortQuery) { |     public List<V> list(Q query, SortQuery sortQuery) { | ||||||
|         List<V> list = this.list(query, sortQuery, voClass); |         List<V> list = this.list(query, sortQuery, voClass); | ||||||
|   | |||||||
| @@ -29,6 +29,9 @@ import cn.hutool.core.lang.tree.TreeUtil; | |||||||
| import cn.hutool.core.lang.tree.parser.NodeParser; | import cn.hutool.core.lang.tree.parser.NodeParser; | ||||||
| import cn.hutool.core.util.ReflectUtil; | import cn.hutool.core.util.ReflectUtil; | ||||||
|  |  | ||||||
|  | import top.charles7c.cnadmin.common.annotation.TreeField; | ||||||
|  | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 树工具类 |  * 树工具类 | ||||||
|  * |  * | ||||||
| @@ -39,7 +42,7 @@ import cn.hutool.core.util.ReflectUtil; | |||||||
| public class TreeUtils { | public class TreeUtils { | ||||||
|  |  | ||||||
|     /** 默认属性配置对象(根据前端树结构灵活调整名称) */ |     /** 默认属性配置对象(根据前端树结构灵活调整名称) */ | ||||||
|     private static final TreeNodeConfig DEFAULT_CONFIG = |     public static final TreeNodeConfig DEFAULT_CONFIG = | ||||||
|         TreeNodeConfig.DEFAULT_CONFIG.setNameKey("title").setIdKey("key").setWeightKey("sort"); |         TreeNodeConfig.DEFAULT_CONFIG.setNameKey("title").setIdKey("key").setWeightKey("sort"); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -53,13 +56,46 @@ public class TreeUtils { | |||||||
|      *            源数据集合 |      *            源数据集合 | ||||||
|      * @param nodeParser |      * @param nodeParser | ||||||
|      *            转换器 |      *            转换器 | ||||||
|      * @return List |      * @return List 树列表 | ||||||
|      */ |      */ | ||||||
|     public static <T, E> List<Tree<E>> build(List<T> list, NodeParser<T, E> nodeParser) { |     public static <T, E> List<Tree<E>> build(List<T> list, NodeParser<T, E> nodeParser) { | ||||||
|  |         return build(list, DEFAULT_CONFIG, nodeParser); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 树构建 | ||||||
|  |      * | ||||||
|  |      * @param <T> | ||||||
|  |      *            转换的实体 为数据源里的对象类型 | ||||||
|  |      * @param <E> | ||||||
|  |      *            ID类型 | ||||||
|  |      * @param list | ||||||
|  |      *            源数据集合 | ||||||
|  |      * @param treeNodeConfig | ||||||
|  |      *            配置 | ||||||
|  |      * @param nodeParser | ||||||
|  |      *            转换器 | ||||||
|  |      * @return List 树列表 | ||||||
|  |      */ | ||||||
|  |     public static <T, E> List<Tree<E>> build(List<T> list, TreeNodeConfig treeNodeConfig, NodeParser<T, E> nodeParser) { | ||||||
|         if (CollUtil.isEmpty(list)) { |         if (CollUtil.isEmpty(list)) { | ||||||
|             return Collections.emptyList(); |             return Collections.emptyList(); | ||||||
|         } |         } | ||||||
|         E parentId = (E)ReflectUtil.getFieldValue(list.get(0), DEFAULT_CONFIG.getParentIdKey()); |         E parentId = (E)ReflectUtil.getFieldValue(list.get(0), treeNodeConfig.getParentIdKey()); | ||||||
|         return TreeUtil.build(list, parentId, DEFAULT_CONFIG, nodeParser); |         return TreeUtil.build(list, parentId, treeNodeConfig, nodeParser); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 根据 @TreeField 配置生成树结构配置 | ||||||
|  |      * | ||||||
|  |      * @param treeField | ||||||
|  |      *            树结构字段注解 | ||||||
|  |      * @return 树结构配置 | ||||||
|  |      */ | ||||||
|  |     public static TreeNodeConfig genTreeNodeConfig(TreeField treeField) { | ||||||
|  |         CheckUtils.throwIfNull(treeField, "请添加并配置 @TreeField 树结构信息"); | ||||||
|  |         return new TreeNodeConfig().setIdKey(treeField.value()).setParentIdKey(treeField.parentIdKey()) | ||||||
|  |             .setNameKey(treeField.nameKey()).setWeightKey(treeField.weightKey()).setChildrenKey(treeField.childrenKey()) | ||||||
|  |             .setDeep(treeField.deep() < 0 ? null : treeField.deep()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,13 +16,12 @@ | |||||||
|  |  | ||||||
| package top.charles7c.cnadmin.system.model.vo; | package top.charles7c.cnadmin.system.model.vo; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| import lombok.experimental.Accessors; | import lombok.experimental.Accessors; | ||||||
|  |  | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  |  | ||||||
|  | import top.charles7c.cnadmin.common.annotation.TreeField; | ||||||
| import top.charles7c.cnadmin.common.base.BaseVO; | import top.charles7c.cnadmin.common.base.BaseVO; | ||||||
| import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | ||||||
|  |  | ||||||
| @@ -34,6 +33,7 @@ import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | |||||||
|  */ |  */ | ||||||
| @Data | @Data | ||||||
| @Accessors(chain = true) | @Accessors(chain = true) | ||||||
|  | @TreeField(value = "deptId", nameKey = "deptName", weightKey = "deptSort") | ||||||
| @Schema(description = "部门信息") | @Schema(description = "部门信息") | ||||||
| public class DeptVO extends BaseVO { | public class DeptVO extends BaseVO { | ||||||
|  |  | ||||||
| @@ -74,10 +74,4 @@ public class DeptVO extends BaseVO { | |||||||
|      */ |      */ | ||||||
|     @Schema(description = "状态(1启用 2禁用)") |     @Schema(description = "状态(1启用 2禁用)") | ||||||
|     private DisEnableStatusEnum status; |     private DisEnableStatusEnum status; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 子部门列表 |  | ||||||
|      */ |  | ||||||
|     @Schema(description = "子部门列表") |  | ||||||
|     private List<DeptVO> children; |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,13 +16,12 @@ | |||||||
|  |  | ||||||
| package top.charles7c.cnadmin.system.model.vo; | package top.charles7c.cnadmin.system.model.vo; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| import lombok.experimental.Accessors; | import lombok.experimental.Accessors; | ||||||
|  |  | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  |  | ||||||
|  | import top.charles7c.cnadmin.common.annotation.TreeField; | ||||||
| import top.charles7c.cnadmin.common.base.BaseVO; | import top.charles7c.cnadmin.common.base.BaseVO; | ||||||
| import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | ||||||
| import top.charles7c.cnadmin.common.enums.MenuTypeEnum; | import top.charles7c.cnadmin.common.enums.MenuTypeEnum; | ||||||
| @@ -35,6 +34,7 @@ import top.charles7c.cnadmin.common.enums.MenuTypeEnum; | |||||||
|  */ |  */ | ||||||
| @Data | @Data | ||||||
| @Accessors(chain = true) | @Accessors(chain = true) | ||||||
|  | @TreeField(value = "menuId", nameKey = "menuName", weightKey = "menuSort") | ||||||
| @Schema(description = "菜单信息") | @Schema(description = "菜单信息") | ||||||
| public class MenuVO extends BaseVO { | public class MenuVO extends BaseVO { | ||||||
|  |  | ||||||
| @@ -123,10 +123,4 @@ public class MenuVO extends BaseVO { | |||||||
|      */ |      */ | ||||||
|     @Schema(description = "状态(1启用 2禁用)") |     @Schema(description = "状态(1启用 2禁用)") | ||||||
|     private DisEnableStatusEnum status; |     private DisEnableStatusEnum status; | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 子菜单列表 |  | ||||||
|      */ |  | ||||||
|     @Schema(description = "子菜单列表") |  | ||||||
|     private List<MenuVO> children; |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,10 +16,6 @@ | |||||||
|  |  | ||||||
| package top.charles7c.cnadmin.system.service; | package top.charles7c.cnadmin.system.service; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import cn.hutool.core.lang.tree.Tree; |  | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.base.BaseService; | import top.charles7c.cnadmin.common.base.BaseService; | ||||||
| import top.charles7c.cnadmin.system.model.query.DeptQuery; | import top.charles7c.cnadmin.system.model.query.DeptQuery; | ||||||
| import top.charles7c.cnadmin.system.model.request.DeptRequest; | import top.charles7c.cnadmin.system.model.request.DeptRequest; | ||||||
| @@ -32,23 +28,4 @@ import top.charles7c.cnadmin.system.model.vo.DeptVO; | |||||||
|  * @author Charles7c |  * @author Charles7c | ||||||
|  * @since 2023/1/22 17:54 |  * @since 2023/1/22 17:54 | ||||||
|  */ |  */ | ||||||
| public interface DeptService extends BaseService<DeptVO, DeptDetailVO, DeptQuery, DeptRequest> { | public interface DeptService extends BaseService<DeptVO, DeptDetailVO, DeptQuery, DeptRequest> {} | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 构建树 |  | ||||||
|      * |  | ||||||
|      * @param list |  | ||||||
|      *            原始列表数据 |  | ||||||
|      * @return 树列表 |  | ||||||
|      */ |  | ||||||
|     List<DeptVO> buildListTree(List<DeptVO> list); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 构建树 |  | ||||||
|      * |  | ||||||
|      * @param list |  | ||||||
|      *            原始列表数据 |  | ||||||
|      * @return 树列表 |  | ||||||
|      */ |  | ||||||
|     List<Tree<Long>> buildTree(List<DeptVO> list); |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -16,10 +16,6 @@ | |||||||
|  |  | ||||||
| package top.charles7c.cnadmin.system.service; | package top.charles7c.cnadmin.system.service; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import cn.hutool.core.lang.tree.Tree; |  | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.base.BaseService; | import top.charles7c.cnadmin.common.base.BaseService; | ||||||
| import top.charles7c.cnadmin.system.model.query.MenuQuery; | import top.charles7c.cnadmin.system.model.query.MenuQuery; | ||||||
| import top.charles7c.cnadmin.system.model.request.MenuRequest; | import top.charles7c.cnadmin.system.model.request.MenuRequest; | ||||||
| @@ -31,23 +27,4 @@ import top.charles7c.cnadmin.system.model.vo.MenuVO; | |||||||
|  * @author Charles7c |  * @author Charles7c | ||||||
|  * @since 2023/2/15 20:30 |  * @since 2023/2/15 20:30 | ||||||
|  */ |  */ | ||||||
| public interface MenuService extends BaseService<MenuVO, MenuVO, MenuQuery, MenuRequest> { | public interface MenuService extends BaseService<MenuVO, MenuVO, MenuQuery, MenuRequest> {} | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 构建树 |  | ||||||
|      * |  | ||||||
|      * @param list |  | ||||||
|      *            原始列表数据 |  | ||||||
|      * @return 树列表 |  | ||||||
|      */ |  | ||||||
|     List<MenuVO> buildListTree(List<MenuVO> list); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 构建树 |  | ||||||
|      * |  | ||||||
|      * @param list |  | ||||||
|      *            原始列表数据 |  | ||||||
|      * @return 树列表 |  | ||||||
|      */ |  | ||||||
|     List<Tree<Long>> buildTree(List<MenuVO> list); |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -16,11 +16,7 @@ | |||||||
|  |  | ||||||
| package top.charles7c.cnadmin.system.service.impl; | package top.charles7c.cnadmin.system.service.impl; | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Objects; |  | ||||||
| import java.util.stream.Collectors; |  | ||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
|  |  | ||||||
| @@ -29,13 +25,9 @@ import lombok.RequiredArgsConstructor; | |||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; |  | ||||||
| import cn.hutool.core.lang.tree.Tree; |  | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.base.BaseServiceImpl; | import top.charles7c.cnadmin.common.base.BaseServiceImpl; | ||||||
| import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | ||||||
| import top.charles7c.cnadmin.common.util.ExceptionUtils; | import top.charles7c.cnadmin.common.util.ExceptionUtils; | ||||||
| import top.charles7c.cnadmin.common.util.TreeUtils; |  | ||||||
| import top.charles7c.cnadmin.common.util.validate.CheckUtils; | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
| import top.charles7c.cnadmin.system.mapper.DeptMapper; | import top.charles7c.cnadmin.system.mapper.DeptMapper; | ||||||
| import top.charles7c.cnadmin.system.model.entity.DeptDO; | import top.charles7c.cnadmin.system.model.entity.DeptDO; | ||||||
| @@ -90,68 +82,6 @@ public class DeptServiceImpl extends BaseServiceImpl<DeptMapper, DeptDO, DeptVO, | |||||||
|         super.lambdaUpdate().in(DeptDO::getParentId, ids).remove(); |         super.lambdaUpdate().in(DeptDO::getParentId, ids).remove(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public List<DeptVO> buildListTree(List<DeptVO> list) { |  | ||||||
|         if (CollUtil.isEmpty(list)) { |  | ||||||
|             return Collections.emptyList(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // 去除重复子部门列表 |  | ||||||
|         List<DeptVO> deDuplicationList = deDuplication(list); |  | ||||||
|         return deDuplicationList.stream().map(d -> d.setChildren(this.getChildren(d, list))) |  | ||||||
|             .collect(Collectors.toList()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 数据去重(去除重复子部门列表) |  | ||||||
|      * |  | ||||||
|      * @param list |  | ||||||
|      *            部门列表 |  | ||||||
|      * @return 去重后部门列表 |  | ||||||
|      */ |  | ||||||
|     private List<DeptVO> deDuplication(List<DeptVO> list) { |  | ||||||
|         List<DeptVO> deDuplicationList = new ArrayList<>(); |  | ||||||
|         for (DeptVO outer : list) { |  | ||||||
|             boolean flag = true; |  | ||||||
|             for (DeptVO inner : list) { |  | ||||||
|                 // 忽略重复子列表 |  | ||||||
|                 if (Objects.equals(inner.getDeptId(), outer.getParentId())) { |  | ||||||
|                     flag = false; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (flag) { |  | ||||||
|                 deDuplicationList.add(outer); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return deDuplicationList; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 获取指定部门的子部门列表 |  | ||||||
|      * |  | ||||||
|      * @param deptVO |  | ||||||
|      *            指定部门 |  | ||||||
|      * @param list |  | ||||||
|      *            部门列表 |  | ||||||
|      * @return 子部门列表 |  | ||||||
|      */ |  | ||||||
|     private List<DeptVO> getChildren(DeptVO deptVO, List<DeptVO> list) { |  | ||||||
|         return list.stream().filter(d -> Objects.equals(d.getParentId(), deptVO.getDeptId())) |  | ||||||
|             .map(d -> d.setChildren(this.getChildren(d, list))).collect(Collectors.toList()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public List<Tree<Long>> buildTree(List<DeptVO> list) { |  | ||||||
|         return TreeUtils.build(list, (d, tree) -> { |  | ||||||
|             tree.setId(d.getDeptId()); |  | ||||||
|             tree.setName(d.getDeptName()); |  | ||||||
|             tree.setParentId(d.getParentId()); |  | ||||||
|             tree.setWeight(d.getDeptSort()); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 检查名称是否存在 |      * 检查名称是否存在 | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -16,23 +16,15 @@ | |||||||
|  |  | ||||||
| package top.charles7c.cnadmin.system.service.impl; | package top.charles7c.cnadmin.system.service.impl; | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Objects; |  | ||||||
| import java.util.stream.Collectors; |  | ||||||
|  |  | ||||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||||
|  |  | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; |  | ||||||
| import cn.hutool.core.lang.tree.Tree; |  | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.base.BaseServiceImpl; | import top.charles7c.cnadmin.common.base.BaseServiceImpl; | ||||||
| import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; | ||||||
| import top.charles7c.cnadmin.common.util.TreeUtils; |  | ||||||
| import top.charles7c.cnadmin.common.util.validate.CheckUtils; | import top.charles7c.cnadmin.common.util.validate.CheckUtils; | ||||||
| import top.charles7c.cnadmin.system.mapper.MenuMapper; | import top.charles7c.cnadmin.system.mapper.MenuMapper; | ||||||
| import top.charles7c.cnadmin.system.model.entity.MenuDO; | import top.charles7c.cnadmin.system.model.entity.MenuDO; | ||||||
| @@ -71,6 +63,7 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO, | |||||||
|         boolean isExists = this.checkNameExists(menuName, request.getParentId(), request.getMenuId()); |         boolean isExists = this.checkNameExists(menuName, request.getParentId(), request.getMenuId()); | ||||||
|         CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", menuName)); |         CheckUtils.throwIf(() -> isExists, String.format("修改失败,'%s'已存在", menuName)); | ||||||
|  |  | ||||||
|  |         // 更新信息 | ||||||
|         super.update(request); |         super.update(request); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -81,68 +74,6 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO, | |||||||
|         super.lambdaUpdate().in(MenuDO::getParentId, ids).remove(); |         super.lambdaUpdate().in(MenuDO::getParentId, ids).remove(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public List<MenuVO> buildListTree(List<MenuVO> list) { |  | ||||||
|         if (CollUtil.isEmpty(list)) { |  | ||||||
|             return Collections.emptyList(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // 去除重复子菜单列表 |  | ||||||
|         List<MenuVO> deDuplicationList = deDuplication(list); |  | ||||||
|         return deDuplicationList.stream().map(m -> m.setChildren(this.getChildren(m, list))) |  | ||||||
|             .collect(Collectors.toList()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 数据去重(去除重复子菜单列表) |  | ||||||
|      * |  | ||||||
|      * @param list |  | ||||||
|      *            菜单列表 |  | ||||||
|      * @return 去重后菜单列表 |  | ||||||
|      */ |  | ||||||
|     private List<MenuVO> deDuplication(List<MenuVO> list) { |  | ||||||
|         List<MenuVO> deDuplicationList = new ArrayList<>(); |  | ||||||
|         for (MenuVO outer : list) { |  | ||||||
|             boolean flag = true; |  | ||||||
|             for (MenuVO inner : list) { |  | ||||||
|                 // 忽略重复子列表 |  | ||||||
|                 if (Objects.equals(inner.getMenuId(), outer.getParentId())) { |  | ||||||
|                     flag = false; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (flag) { |  | ||||||
|                 deDuplicationList.add(outer); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return deDuplicationList; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 获取指定菜单的子菜单列表 |  | ||||||
|      * |  | ||||||
|      * @param menuVO |  | ||||||
|      *            指定菜单 |  | ||||||
|      * @param list |  | ||||||
|      *            菜单列表 |  | ||||||
|      * @return 子菜单列表 |  | ||||||
|      */ |  | ||||||
|     private List<MenuVO> getChildren(MenuVO menuVO, List<MenuVO> list) { |  | ||||||
|         return list.stream().filter(m -> Objects.equals(m.getParentId(), menuVO.getMenuId())) |  | ||||||
|             .map(m -> m.setChildren(this.getChildren(m, list))).collect(Collectors.toList()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public List<Tree<Long>> buildTree(List<MenuVO> list) { |  | ||||||
|         return TreeUtils.build(list, (m, tree) -> { |  | ||||||
|             tree.setId(m.getMenuId()); |  | ||||||
|             tree.setName(m.getMenuName()); |  | ||||||
|             tree.setParentId(m.getParentId()); |  | ||||||
|             tree.setWeight(m.getMenuSort()); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 检查名称是否存在 |      * 检查名称是否存在 | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ export interface DeptParam { | |||||||
| } | } | ||||||
|  |  | ||||||
| export function listDept(params: DeptParam) { | export function listDept(params: DeptParam) { | ||||||
|   return axios.get<DeptRecord[]>(`${BASE_URL}/list`, { |   return axios.get<DeptRecord[]>(`${BASE_URL}/tree`, { | ||||||
|     params, |     params, | ||||||
|     paramsSerializer: (obj) => { |     paramsSerializer: (obj) => { | ||||||
|       return qs.stringify(obj); |       return qs.stringify(obj); | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ export interface MenuParam { | |||||||
| } | } | ||||||
|  |  | ||||||
| export function listMenu(params: MenuParam) { | export function listMenu(params: MenuParam) { | ||||||
|   return axios.get<MenuRecord[]>(`${BASE_URL}/list`, { |   return axios.get<MenuRecord[]>(`${BASE_URL}/tree`, { | ||||||
|     params, |     params, | ||||||
|     paramsSerializer: (obj) => { |     paramsSerializer: (obj) => { | ||||||
|       return qs.stringify(obj); |       return qs.stringify(obj); | ||||||
|   | |||||||
| @@ -40,8 +40,6 @@ import top.charles7c.cnadmin.system.model.query.DeptQuery; | |||||||
| import top.charles7c.cnadmin.system.model.query.MenuQuery; | import top.charles7c.cnadmin.system.model.query.MenuQuery; | ||||||
| import top.charles7c.cnadmin.system.model.query.PostQuery; | import top.charles7c.cnadmin.system.model.query.PostQuery; | ||||||
| import top.charles7c.cnadmin.system.model.query.RoleQuery; | import top.charles7c.cnadmin.system.model.query.RoleQuery; | ||||||
| import top.charles7c.cnadmin.system.model.vo.DeptVO; |  | ||||||
| import top.charles7c.cnadmin.system.model.vo.MenuVO; |  | ||||||
| import top.charles7c.cnadmin.system.model.vo.PostVO; | import top.charles7c.cnadmin.system.model.vo.PostVO; | ||||||
| import top.charles7c.cnadmin.system.model.vo.RoleVO; | import top.charles7c.cnadmin.system.model.vo.RoleVO; | ||||||
| import top.charles7c.cnadmin.system.service.DeptService; | import top.charles7c.cnadmin.system.service.DeptService; | ||||||
| @@ -72,16 +70,14 @@ public class CommonController { | |||||||
|     @Operation(summary = "查询部门树", description = "查询树结构的部门列表") |     @Operation(summary = "查询部门树", description = "查询树结构的部门列表") | ||||||
|     @GetMapping("/tree/dept") |     @GetMapping("/tree/dept") | ||||||
|     public R<List<Tree<Long>>> listDeptTree(@Validated DeptQuery query, @Validated SortQuery sortQuery) { |     public R<List<Tree<Long>>> listDeptTree(@Validated DeptQuery query, @Validated SortQuery sortQuery) { | ||||||
|         List<DeptVO> list = deptService.list(query, sortQuery); |         List<Tree<Long>> treeList = deptService.tree(query, sortQuery, true); | ||||||
|         List<Tree<Long>> treeList = deptService.buildTree(list); |  | ||||||
|         return R.ok(treeList); |         return R.ok(treeList); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Operation(summary = "查询菜单树", description = "查询树结构的菜单列表") |     @Operation(summary = "查询菜单树", description = "查询树结构的菜单列表") | ||||||
|     @GetMapping("/tree/menu") |     @GetMapping("/tree/menu") | ||||||
|     public R<List<Tree<Long>>> listMenuTree(@Validated MenuQuery query, @Validated SortQuery sortQuery) { |     public R<List<Tree<Long>>> listMenuTree(@Validated MenuQuery query, @Validated SortQuery sortQuery) { | ||||||
|         List<MenuVO> list = menuService.list(query, sortQuery); |         List<Tree<Long>> treeList = menuService.tree(query, sortQuery, true); | ||||||
|         List<Tree<Long>> treeList = menuService.buildTree(list); |  | ||||||
|         return R.ok(treeList); |         return R.ok(treeList); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,18 +18,12 @@ package top.charles7c.cnadmin.webapi.controller.system; | |||||||
|  |  | ||||||
| import static top.charles7c.cnadmin.common.annotation.CrudRequestMapping.Api; | import static top.charles7c.cnadmin.common.annotation.CrudRequestMapping.Api; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import io.swagger.v3.oas.annotations.Operation; |  | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; | import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
|  |  | ||||||
| import org.springframework.validation.annotation.Validated; |  | ||||||
| import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.annotation.CrudRequestMapping; | import top.charles7c.cnadmin.common.annotation.CrudRequestMapping; | ||||||
| import top.charles7c.cnadmin.common.base.BaseController; | import top.charles7c.cnadmin.common.base.BaseController; | ||||||
| import top.charles7c.cnadmin.common.model.query.SortQuery; |  | ||||||
| import top.charles7c.cnadmin.common.model.vo.R; |  | ||||||
| import top.charles7c.cnadmin.system.model.query.DeptQuery; | import top.charles7c.cnadmin.system.model.query.DeptQuery; | ||||||
| import top.charles7c.cnadmin.system.model.request.DeptRequest; | import top.charles7c.cnadmin.system.model.request.DeptRequest; | ||||||
| import top.charles7c.cnadmin.system.model.vo.DeptDetailVO; | import top.charles7c.cnadmin.system.model.vo.DeptDetailVO; | ||||||
| @@ -44,13 +38,5 @@ import top.charles7c.cnadmin.system.service.DeptService; | |||||||
|  */ |  */ | ||||||
| @Tag(name = "部门管理 API") | @Tag(name = "部门管理 API") | ||||||
| @RestController | @RestController | ||||||
| @CrudRequestMapping(value = "/system/dept", api = {Api.LIST, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT}) | @CrudRequestMapping(value = "/system/dept", api = {Api.TREE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT}) | ||||||
| public class DeptController extends BaseController<DeptService, DeptVO, DeptDetailVO, DeptQuery, DeptRequest> { | public class DeptController extends BaseController<DeptService, DeptVO, DeptDetailVO, DeptQuery, DeptRequest> {} | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     @Operation(summary = "查询列表树") |  | ||||||
|     public R<List<DeptVO>> list(@Validated DeptQuery query, @Validated SortQuery sortQuery) { |  | ||||||
|         List<DeptVO> list = baseService.list(query, sortQuery); |  | ||||||
|         return R.ok(baseService.buildListTree(list)); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -18,18 +18,12 @@ package top.charles7c.cnadmin.webapi.controller.system; | |||||||
|  |  | ||||||
| import static top.charles7c.cnadmin.common.annotation.CrudRequestMapping.Api; | import static top.charles7c.cnadmin.common.annotation.CrudRequestMapping.Api; | ||||||
|  |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import io.swagger.v3.oas.annotations.Operation; |  | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; | import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
|  |  | ||||||
| import org.springframework.validation.annotation.Validated; |  | ||||||
| import org.springframework.web.bind.annotation.RestController; | import org.springframework.web.bind.annotation.RestController; | ||||||
|  |  | ||||||
| import top.charles7c.cnadmin.common.annotation.CrudRequestMapping; | import top.charles7c.cnadmin.common.annotation.CrudRequestMapping; | ||||||
| import top.charles7c.cnadmin.common.base.BaseController; | import top.charles7c.cnadmin.common.base.BaseController; | ||||||
| import top.charles7c.cnadmin.common.model.query.SortQuery; |  | ||||||
| import top.charles7c.cnadmin.common.model.vo.R; |  | ||||||
| import top.charles7c.cnadmin.system.model.query.MenuQuery; | import top.charles7c.cnadmin.system.model.query.MenuQuery; | ||||||
| import top.charles7c.cnadmin.system.model.request.MenuRequest; | import top.charles7c.cnadmin.system.model.request.MenuRequest; | ||||||
| import top.charles7c.cnadmin.system.model.vo.MenuVO; | import top.charles7c.cnadmin.system.model.vo.MenuVO; | ||||||
| @@ -43,13 +37,5 @@ import top.charles7c.cnadmin.system.service.MenuService; | |||||||
|  */ |  */ | ||||||
| @Tag(name = "菜单管理 API") | @Tag(name = "菜单管理 API") | ||||||
| @RestController | @RestController | ||||||
| @CrudRequestMapping(value = "/system/menu", api = {Api.LIST, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT}) | @CrudRequestMapping(value = "/system/menu", api = {Api.TREE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT}) | ||||||
| public class MenuController extends BaseController<MenuService, MenuVO, MenuVO, MenuQuery, MenuRequest> { | public class MenuController extends BaseController<MenuService, MenuVO, MenuVO, MenuQuery, MenuRequest> {} | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     @Operation(summary = "查询列表树") |  | ||||||
|     public R<List<MenuVO>> list(@Validated MenuQuery query, @Validated SortQuery sortQuery) { |  | ||||||
|         List<MenuVO> list = baseService.list(query, sortQuery); |  | ||||||
|         return R.ok(baseService.buildListTree(list)); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user