Skip to content

Commit

Permalink
feat(extension/crud): 支持树结构全局配置
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles7c committed Oct 13, 2024
1 parent 679cae1 commit 5891c4a
Show file tree
Hide file tree
Showing 13 changed files with 333 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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";

/**
* 数据权限配置
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,11 @@
* @return 递归深度
*/
int deep() default -1;

/**
* 根节点 ID
*
* @return 根节点 ID
*/
long rootId() default 0L;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* 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
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
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;
Expand All @@ -36,6 +37,7 @@
* @since 1.0.0
*/
@Configuration
@EnableConfigurationProperties(CrudProperties.class)
public class CrudRestControllerAutoConfiguration extends DelegatingWebMvcConfiguration {

private static final Logger log = LoggerFactory.getLogger(CrudRestControllerAutoConfiguration.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
* <p>
* 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
* <p>
* http://www.gnu.org/licenses/lgpl.html
* <p>
* 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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,34 +28,42 @@ public enum Api {
* 所有 API
*/
ALL,

/**
* 分页
*/
PAGE,
/**
* 树列表
*/
TREE,

/**
* 列表
*/
LIST,

/**
* 树列表
*/
TREE,

/**
* 详情
*/
GET,

/**
* 新增
*/
ADD,

/**
* 修改
*/
UPDATE,

/**
* 删除
*/
DELETE,

/**
* 导出
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
* 树工具类
*
Expand All @@ -37,7 +29,7 @@
public class TreeUtils {

/**
* 默认字段配置对象(根据前端树结构灵活调整名称)
* 默认字段配置对象
*/
public static final TreeNodeConfig DEFAULT_CONFIG = TreeNodeConfig.DEFAULT_CONFIG.setNameKey("title")
.setIdKey("key")
Expand All @@ -46,37 +38,6 @@ public class TreeUtils {
private TreeUtils() {
}

/**
* 树构建
*
* @param <T> 转换的实体 为数据源里的对象类型
* @param <E> ID类型
* @param list 源数据集合
* @param nodeParser 转换器
* @return List 树列表
*/
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)) {
return new ArrayList<>(0);
}
E parentId = (E)ReflectUtil.getFieldValue(list.get(0), treeNodeConfig.getParentIdKey());
return TreeUtil.build(list, parentId, treeNodeConfig, nodeParser);
}

/**
* 根据 @TreeField 配置生成树结构配置
*
Expand Down
Loading

0 comments on commit 5891c4a

Please sign in to comment.