From 5891c4aa61b14ba11a387a478fb3616dfc52217c Mon Sep 17 00:00:00 2001 From: Charles7c Date: Sun, 13 Oct 2024 21:23:31 +0800 Subject: [PATCH] =?UTF-8?q?feat(extension/crud):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=A0=91=E7=BB=93=E6=9E=84=E5=85=A8=E5=B1=80=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/constant/PropertiesConstants.java | 5 + .../extension/crud/annotation/TreeField.java | 7 + .../crud/autoconfigure/CrudProperties.java | 45 +++++ .../CrudRestControllerAutoConfiguration.java | 2 + .../autoconfigure/CrudTreeProperties.java | 155 ++++++++++++++++++ .../starter/extension/crud/enums/Api.java | 16 +- .../extension/crud/util/TreeUtils.java | 41 +---- .../crud/controller/BaseController.java | 30 ++-- .../extension/crud/service/BaseService.java | 24 +-- .../crud/service/impl/BaseServiceImpl.java | 51 +++--- .../crud/controller/BaseController.java | 30 ++-- .../extension/crud/service/BaseService.java | 24 +-- .../crud/service/impl/BaseServiceImpl.java | 52 +++--- 13 files changed, 345 insertions(+), 137 deletions(-) create mode 100644 continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudProperties.java create mode 100644 continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudTreeProperties.java diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/constant/PropertiesConstants.java b/continew-starter-core/src/main/java/top/continew/starter/core/constant/PropertiesConstants.java index a335a391..3f52847e 100644 --- a/continew-starter-core/src/main/java/top/continew/starter/core/constant/PropertiesConstants.java +++ b/continew-starter-core/src/main/java/top/continew/starter/core/constant/PropertiesConstants.java @@ -119,6 +119,11 @@ public class PropertiesConstants { */ public static final String MESSAGING_WEBSOCKET = MESSAGING + StringConstants.DOT + "websocket"; + /** + * CRUD 配置 + */ + public static final String CRUD = CONTINEW_STARTER + StringConstants.DOT + "crud"; + /** * 数据权限配置 */ diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/annotation/TreeField.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/annotation/TreeField.java index f02b090c..9d207cc3 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/annotation/TreeField.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/annotation/TreeField.java @@ -71,4 +71,11 @@ public @interface TreeField { * @return 递归深度 */ int deep() default -1; + + /** + * 根节点 ID + * + * @return 根节点 ID + */ + long rootId() default 0L; } diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudProperties.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudProperties.java new file mode 100644 index 00000000..b7a92030 --- /dev/null +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudProperties.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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.continew.starter.extension.crud.autoconfigure; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; +import top.continew.starter.core.constant.PropertiesConstants; + +/** + * CRUD 配置属性 + * + * @author Charles7c + * @since 2.7.2 + */ +@ConfigurationProperties(PropertiesConstants.CRUD) +public class CrudProperties { + + /** + * 树配置 + */ + @NestedConfigurationProperty + private CrudTreeProperties tree; + + public CrudTreeProperties getTree() { + return tree; + } + + public void setTree(CrudTreeProperties tree) { + this.tree = tree; + } +} diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudRestControllerAutoConfiguration.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudRestControllerAutoConfiguration.java index 70117f03..7780943b 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudRestControllerAutoConfiguration.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudRestControllerAutoConfiguration.java @@ -20,6 +20,7 @@ import jakarta.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -36,6 +37,7 @@ import org.springframework.web.servlet.resource.ResourceUrlProvider; * @since 1.0.0 */ @Configuration +@EnableConfigurationProperties(CrudProperties.class) public class CrudRestControllerAutoConfiguration extends DelegatingWebMvcConfiguration { private static final Logger log = LoggerFactory.getLogger(CrudRestControllerAutoConfiguration.class); diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudTreeProperties.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudTreeProperties.java new file mode 100644 index 00000000..a90dbe11 --- /dev/null +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/autoconfigure/CrudTreeProperties.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * 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.continew.starter.extension.crud.autoconfigure; + +import cn.hutool.core.lang.tree.TreeNodeConfig; +import top.continew.starter.core.util.validate.CheckUtils; +import top.continew.starter.extension.crud.annotation.TreeField; + +/** + * CRUD 树列表配置属性 + * + * @author Charles7c + * @since 2.7.2 + */ +public class CrudTreeProperties { + + /** + * ID 字段名 + */ + private String idKey = "id"; + + /** + * 父 ID 字段名 + * + */ + private String parentIdKey = "parentId"; + + /** + * 名称字段名 + * + */ + private String nameKey = "name"; + + /** + * 排序字段名 + * + */ + private String weightKey = "weight"; + + /** + * 子列表字段名 + * + */ + private String childrenKey = "children"; + + /** + * 递归深度(< 0 不限制) + */ + private Integer deep = -1; + + /** + * 根节点 ID + */ + private Long rootId = 0L; + + public String getIdKey() { + return idKey; + } + + public void setIdKey(String idKey) { + this.idKey = idKey; + } + + public String getParentIdKey() { + return parentIdKey; + } + + public void setParentIdKey(String parentIdKey) { + this.parentIdKey = parentIdKey; + } + + public String getNameKey() { + return nameKey; + } + + public void setNameKey(String nameKey) { + this.nameKey = nameKey; + } + + public String getWeightKey() { + return weightKey; + } + + public void setWeightKey(String weightKey) { + this.weightKey = weightKey; + } + + public String getChildrenKey() { + return childrenKey; + } + + public void setChildrenKey(String childrenKey) { + this.childrenKey = childrenKey; + } + + public Integer getDeep() { + return deep; + } + + public void setDeep(Integer deep) { + this.deep = deep; + } + + public Long getRootId() { + return rootId; + } + + public void setRootId(Long rootId) { + this.rootId = rootId; + } + + /** + * 生成 {@link TreeNodeConfig} 对象 + * + * @return {@link TreeNodeConfig} 对象 + */ + public TreeNodeConfig genTreeNodeConfig() { + return TreeNodeConfig.DEFAULT_CONFIG.setIdKey(idKey) + .setParentIdKey(parentIdKey) + .setNameKey(nameKey) + .setWeightKey(weightKey) + .setChildrenKey(childrenKey) + .setDeep(deep < 0 ? null : deep); + } + + /** + * 根据 @TreeField 配置生成树结构配置 + * + * @param treeField 树结构字段注解 + * @return 树结构配置 + */ + public 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()); + } +} diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/enums/Api.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/enums/Api.java index abbcec7c..e451f922 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/enums/Api.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/enums/Api.java @@ -28,34 +28,42 @@ public enum Api { * 所有 API */ ALL, + /** * 分页 */ PAGE, - /** - * 树列表 - */ - TREE, + /** * 列表 */ LIST, + + /** + * 树列表 + */ + TREE, + /** * 详情 */ GET, + /** * 新增 */ ADD, + /** * 修改 */ UPDATE, + /** * 删除 */ DELETE, + /** * 导出 */ diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/util/TreeUtils.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/util/TreeUtils.java index 8db19fab..d1b97f6f 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/util/TreeUtils.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-core/src/main/java/top/continew/starter/extension/crud/util/TreeUtils.java @@ -16,18 +16,10 @@ package top.continew.starter.extension.crud.util; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNodeConfig; -import cn.hutool.core.lang.tree.TreeUtil; -import cn.hutool.core.lang.tree.parser.NodeParser; -import cn.hutool.core.util.ReflectUtil; import top.continew.starter.core.util.validate.CheckUtils; import top.continew.starter.extension.crud.annotation.TreeField; -import java.util.ArrayList; -import java.util.List; - /** * 树工具类 * @@ -37,7 +29,7 @@ import java.util.List; public class TreeUtils { /** - * 默认字段配置对象(根据前端树结构灵活调整名称) + * 默认字段配置对象 */ public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("title") .setIdKey("key") @@ -46,37 +38,6 @@ public class TreeUtils { private TreeUtils() { } - /** - * 树构建 - * - * @param 转换的实体 为数据源里的对象类型 - * @param ID类型 - * @param list 源数据集合 - * @param nodeParser 转换器 - * @return List 树列表 - */ - public static List> build(List list, NodeParser nodeParser) { - return build(list, DEFAULT_CONFIG, nodeParser); - } - - /** - * 树构建 - * - * @param 转换的实体 为数据源里的对象类型 - * @param ID类型 - * @param list 源数据集合 - * @param treeNodeConfig 配置 - * @param nodeParser 转换器 - * @return List 树列表 - */ - public static List> build(List list, TreeNodeConfig treeNodeConfig, NodeParser nodeParser) { - if (CollUtil.isEmpty(list)) { - return new ArrayList<>(0); - } - E parentId = (E)ReflectUtil.getFieldValue(list.get(0), treeNodeConfig.getParentIdKey()); - return TreeUtil.build(list, parentId, treeNodeConfig, nodeParser); - } - /** * 根据 @TreeField 配置生成树结构配置 * diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/controller/BaseController.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/controller/BaseController.java index 0aaa0916..3dd37ec4 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/controller/BaseController.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/controller/BaseController.java @@ -71,21 +71,6 @@ public abstract class BaseController, L, D, Q, return baseService.page(query, pageQuery); } - /** - * 查询树列表 - * - * @param query 查询条件 - * @param sortQuery 排序查询条件 - * @return 树列表信息 - */ - @Operation(summary = "查询树列表", description = "查询树列表") - @ResponseBody - @GetMapping("/tree") - public List> tree(Q query, SortQuery sortQuery) { - this.checkPermission(Api.LIST); - return baseService.tree(query, sortQuery, false); - } - /** * 查询列表 * @@ -101,6 +86,21 @@ public abstract class BaseController, L, D, Q, return baseService.list(query, sortQuery); } + /** + * 查询树列表 + * + * @param query 查询条件 + * @param sortQuery 排序查询条件 + * @return 树列表信息 + */ + @Operation(summary = "查询树列表", description = "查询树列表") + @ResponseBody + @GetMapping("/tree") + public List> tree(Q query, SortQuery sortQuery) { + this.checkPermission(Api.LIST); + return baseService.tree(query, sortQuery, false); + } + /** * 查询详情 * diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/service/BaseService.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/service/BaseService.java index e4095d54..9687de11 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/service/BaseService.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/service/BaseService.java @@ -46,16 +46,6 @@ public interface BaseService { */ PageResp page(Q query, PageQuery pageQuery); - /** - * 查询树列表 - * - * @param query 查询条件 - * @param sortQuery 排序查询条件 - * @param isSimple 是否为简单树结构(不包含基本树结构之外的扩展字段) - * @return 树列表信息 - */ - List> tree(Q query, SortQuery sortQuery, boolean isSimple); - /** * 查询列表 * @@ -65,6 +55,20 @@ public interface BaseService { */ List list(Q query, SortQuery sortQuery); + /** + * 查询树列表 + *

+ * 虽然提供了查询条件,但不建议使用,容易因缺失根节点导致树节点丢失。 + * 建议在前端进行查询过滤,如需使用建议重写方法。 + *

+ * + * @param query 查询条件 + * @param sortQuery 排序查询条件 + * @param isSimple 是否为简单树结构(不包含基本树结构之外的扩展字段) + * @return 树列表信息 + */ + List> tree(Q query, SortQuery sortQuery, boolean isSimple); + /** * 查看详情 * diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/service/impl/BaseServiceImpl.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/service/impl/BaseServiceImpl.java index b2838a39..c344278a 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/service/impl/BaseServiceImpl.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mf/src/main/java/top/continew/starter/extension/crud/service/impl/BaseServiceImpl.java @@ -22,12 +22,14 @@ import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.extra.spring.SpringUtil; import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.query.QueryWrapper; import jakarta.servlet.http.HttpServletResponse; +import org.apache.poi.ss.formula.functions.T; import org.springframework.data.domain.Sort; import org.springframework.transaction.annotation.Transactional; import top.continew.starter.core.constant.StringConstants; @@ -37,12 +39,13 @@ import top.continew.starter.data.mf.base.BaseMapper; import top.continew.starter.data.mf.service.impl.ServiceImpl; import top.continew.starter.data.mf.util.QueryWrapperHelper; import top.continew.starter.extension.crud.annotation.TreeField; +import top.continew.starter.extension.crud.autoconfigure.CrudProperties; +import top.continew.starter.extension.crud.autoconfigure.CrudTreeProperties; import top.continew.starter.extension.crud.model.entity.BaseIdDO; import top.continew.starter.extension.crud.model.query.PageQuery; import top.continew.starter.extension.crud.model.query.SortQuery; import top.continew.starter.extension.crud.model.resp.PageResp; import top.continew.starter.extension.crud.service.BaseService; -import top.continew.starter.extension.crud.util.TreeUtils; import top.continew.starter.file.excel.util.ExcelUtils; import java.lang.reflect.Field; @@ -79,6 +82,13 @@ public abstract class BaseServiceImpl, T extends BaseIdD return pageResp; } + @Override + public List list(Q query, SortQuery sortQuery) { + List list = this.list(query, sortQuery, listClass); + list.forEach(this::fill); + return list; + } + @Override public List> tree(Q query, SortQuery sortQuery, boolean isSimple) { List list = this.list(query, sortQuery); @@ -86,36 +96,35 @@ public abstract class BaseServiceImpl, T extends BaseIdD return new ArrayList<>(0); } // 如果构建简单树结构,则不包含基本树结构之外的扩展字段 - TreeNodeConfig treeNodeConfig = TreeUtils.DEFAULT_CONFIG; - TreeField treeField = listClass.getDeclaredAnnotation(TreeField.class); - if (!isSimple) { - // 根据 @TreeField 配置生成树结构配置 - treeNodeConfig = TreeUtils.genTreeNodeConfig(treeField); + CrudProperties crudProperties = SpringUtil.getBean(CrudProperties.class); + CrudTreeProperties treeProperties = crudProperties.getTree(); + TreeNodeConfig treeNodeConfig; + Long rootId; + if (isSimple) { + treeNodeConfig = treeProperties.genTreeNodeConfig(); + rootId = treeProperties.getRootId(); + } else { + TreeField treeField = listClass.getDeclaredAnnotation(TreeField.class); + treeNodeConfig = treeProperties.genTreeNodeConfig(treeField); + rootId = treeField.rootId(); } // 构建树 - return TreeUtils.build(list, treeNodeConfig, (node, tree) -> { - // 转换器 - tree.setId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.value()))); - tree.setParentId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.parentIdKey()))); - tree.setName(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.nameKey()))); - tree.setWeight(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.weightKey()))); + return TreeUtil.build(list, rootId, treeNodeConfig, (node, tree) -> { + tree.setId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeNodeConfig.getIdKey()))); + tree.setParentId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeNodeConfig.getParentIdKey()))); + tree.setName(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeNodeConfig.getNameKey()))); + tree.setWeight(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeNodeConfig.getWeightKey()))); if (!isSimple) { List fieldList = ReflectUtils.getNonStaticFields(listClass); - fieldList.removeIf(f -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), treeField.value(), treeField - .parentIdKey(), treeField.nameKey(), treeField.weightKey(), treeField.childrenKey())); + fieldList.removeIf(f -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), treeNodeConfig + .getIdKey(), treeNodeConfig.getParentIdKey(), treeNodeConfig.getNameKey(), treeNodeConfig + .getWeightKey(), treeNodeConfig.getChildrenKey())); fieldList.forEach(f -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, CharSequenceUtil.genGetter(f .getName())))); } }); } - @Override - public List list(Q query, SortQuery sortQuery) { - List list = this.list(query, sortQuery, listClass); - list.forEach(this::fill); - return list; - } - @Override public D get(Long id) { T entity = super.getById(id); diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/controller/BaseController.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/controller/BaseController.java index 0aaa0916..3dd37ec4 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/controller/BaseController.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/controller/BaseController.java @@ -71,21 +71,6 @@ public abstract class BaseController, L, D, Q, return baseService.page(query, pageQuery); } - /** - * 查询树列表 - * - * @param query 查询条件 - * @param sortQuery 排序查询条件 - * @return 树列表信息 - */ - @Operation(summary = "查询树列表", description = "查询树列表") - @ResponseBody - @GetMapping("/tree") - public List> tree(Q query, SortQuery sortQuery) { - this.checkPermission(Api.LIST); - return baseService.tree(query, sortQuery, false); - } - /** * 查询列表 * @@ -101,6 +86,21 @@ public abstract class BaseController, L, D, Q, return baseService.list(query, sortQuery); } + /** + * 查询树列表 + * + * @param query 查询条件 + * @param sortQuery 排序查询条件 + * @return 树列表信息 + */ + @Operation(summary = "查询树列表", description = "查询树列表") + @ResponseBody + @GetMapping("/tree") + public List> tree(Q query, SortQuery sortQuery) { + this.checkPermission(Api.LIST); + return baseService.tree(query, sortQuery, false); + } + /** * 查询详情 * diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/BaseService.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/BaseService.java index d163c3ae..e099eed5 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/BaseService.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/BaseService.java @@ -46,16 +46,6 @@ public interface BaseService { */ PageResp page(Q query, PageQuery pageQuery); - /** - * 查询树列表 - * - * @param query 查询条件 - * @param sortQuery 排序查询条件 - * @param isSimple 是否为简单树结构(不包含基本树结构之外的扩展字段) - * @return 树列表信息 - */ - List> tree(Q query, SortQuery sortQuery, boolean isSimple); - /** * 查询列表 * @@ -65,6 +55,20 @@ public interface BaseService { */ List list(Q query, SortQuery sortQuery); + /** + * 查询树列表 + *

+ * 虽然提供了查询条件,但不建议使用,容易因缺失根节点导致树节点丢失。 + * 建议在前端进行查询过滤,如需使用建议重写方法。 + *

+ * + * @param query 查询条件 + * @param sortQuery 排序查询条件 + * @param isSimple 是否为简单树结构(不包含基本树结构之外的扩展字段) + * @return 树列表信息 + */ + List> tree(Q query, SortQuery sortQuery, boolean isSimple); + /** * 查询详情 * diff --git a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/impl/BaseServiceImpl.java b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/impl/BaseServiceImpl.java index 0919e0f5..f1bac703 100644 --- a/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/impl/BaseServiceImpl.java +++ b/continew-starter-extension/continew-starter-extension-crud/continew-starter-extension-crud-mp/src/main/java/top/continew/starter/extension/crud/service/impl/BaseServiceImpl.java @@ -22,6 +22,7 @@ import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNodeConfig; +import cn.hutool.core.lang.tree.TreeUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.ReflectUtil; @@ -42,13 +43,14 @@ import top.continew.starter.data.mp.service.impl.ServiceImpl; import top.continew.starter.data.mp.util.QueryWrapperHelper; import top.continew.starter.extension.crud.annotation.DictField; import top.continew.starter.extension.crud.annotation.TreeField; +import top.continew.starter.extension.crud.autoconfigure.CrudProperties; +import top.continew.starter.extension.crud.autoconfigure.CrudTreeProperties; import top.continew.starter.extension.crud.model.entity.BaseIdDO; import top.continew.starter.extension.crud.model.query.PageQuery; import top.continew.starter.extension.crud.model.query.SortQuery; import top.continew.starter.extension.crud.model.resp.LabelValueResp; import top.continew.starter.extension.crud.model.resp.PageResp; import top.continew.starter.extension.crud.service.BaseService; -import top.continew.starter.extension.crud.util.TreeUtils; import top.continew.starter.file.excel.util.ExcelUtils; import java.lang.reflect.Field; @@ -86,6 +88,13 @@ public abstract class BaseServiceImpl, T extends BaseIdD return pageResp; } + @Override + public List list(Q query, SortQuery sortQuery) { + List list = this.list(query, sortQuery, this.getListClass()); + list.forEach(this::fill); + return list; + } + @Override public List> tree(Q query, SortQuery sortQuery, boolean isSimple) { List list = this.list(query, sortQuery); @@ -93,36 +102,35 @@ public abstract class BaseServiceImpl, T extends BaseIdD return new ArrayList<>(0); } // 如果构建简单树结构,则不包含基本树结构之外的扩展字段 - TreeNodeConfig treeNodeConfig = TreeUtils.DEFAULT_CONFIG; - TreeField treeField = this.getListClass().getDeclaredAnnotation(TreeField.class); - if (!isSimple) { - // 根据 @TreeField 配置生成树结构配置 - treeNodeConfig = TreeUtils.genTreeNodeConfig(treeField); + CrudProperties crudProperties = SpringUtil.getBean(CrudProperties.class); + CrudTreeProperties treeProperties = crudProperties.getTree(); + TreeNodeConfig treeNodeConfig; + Long rootId; + if (isSimple) { + treeNodeConfig = treeProperties.genTreeNodeConfig(); + rootId = treeProperties.getRootId(); + } else { + TreeField treeField = listClass.getDeclaredAnnotation(TreeField.class); + treeNodeConfig = treeProperties.genTreeNodeConfig(treeField); + rootId = treeField.rootId(); } // 构建树 - return TreeUtils.build(list, treeNodeConfig, (node, tree) -> { - // 转换器 - tree.setId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.value()))); - tree.setParentId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.parentIdKey()))); - tree.setName(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.nameKey()))); - tree.setWeight(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.weightKey()))); + return TreeUtil.build(list, rootId, treeNodeConfig, (node, tree) -> { + tree.setId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeNodeConfig.getIdKey()))); + tree.setParentId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeNodeConfig.getParentIdKey()))); + tree.setName(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeNodeConfig.getNameKey()))); + tree.setWeight(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeNodeConfig.getWeightKey()))); if (!isSimple) { - List fieldList = ReflectUtils.getNonStaticFields(this.getListClass()); - fieldList.removeIf(f -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), treeField.value(), treeField - .parentIdKey(), treeField.nameKey(), treeField.weightKey(), treeField.childrenKey())); + List fieldList = ReflectUtils.getNonStaticFields(listClass); + fieldList.removeIf(f -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), treeNodeConfig + .getIdKey(), treeNodeConfig.getParentIdKey(), treeNodeConfig.getNameKey(), treeNodeConfig + .getWeightKey(), treeNodeConfig.getChildrenKey())); fieldList.forEach(f -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, CharSequenceUtil.genGetter(f .getName())))); } }); } - @Override - public List list(Q query, SortQuery sortQuery) { - List list = this.list(query, sortQuery, this.getListClass()); - list.forEach(this::fill); - return list; - } - @Override public D get(Long id) { T entity = super.getById(id, false);