diff --git a/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TreeConstants.java b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TreeConstants.java
new file mode 100644
index 00000000..ed7ec737
--- /dev/null
+++ b/opsli-base-support/opsli-common/src/main/java/org/opsli/common/constants/TreeConstants.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
+ *
+ * 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 org.opsli.common.constants;
+
+/**
+ * 菜单常量
+ *
+ * @author Parker
+ * @date 2021年3月10日15:50:16
+ */
+public interface TreeConstants {
+
+ /** 是否包含子集 */
+ String HAS_CHILDREN = "hasChildren";
+
+
+ /** 是否是叶子节点 */
+ String IS_LEAF = "isLeaf";
+
+}
diff --git a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java
index 373b6da5..e25d33a0 100644
--- a/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java
+++ b/opsli-base-support/opsli-core/src/main/java/org/opsli/core/base/controller/BaseRestController.java
@@ -17,13 +17,19 @@ package org.opsli.core.base.controller;
import cn.hutool.core.annotation.AnnotationUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
+import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.result.ResultVo;
@@ -32,6 +38,7 @@ import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.annotation.hotdata.EnableHotData;
import org.opsli.common.constants.CacheConstants;
+import org.opsli.common.constants.TreeConstants;
import org.opsli.common.enums.ExcelOperate;
import org.opsli.common.exception.ServiceException;
import org.opsli.common.exception.TokenException;
@@ -40,6 +47,7 @@ import org.opsli.common.utils.OutputStreamUtil;
import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.autoconfigure.properties.GlobalProperties;
import org.opsli.core.base.entity.BaseEntity;
+import org.opsli.core.base.entity.HasChildren;
import org.opsli.core.base.service.interfaces.CrudServiceInterface;
import org.opsli.core.cache.local.CacheUtil;
import org.opsli.core.msg.CoreMsg;
@@ -60,9 +68,8 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
+import java.util.function.Function;
/**
* 默认 范型引用 子类的Service , 为简单的CRUD做足准备
@@ -353,6 +360,67 @@ public abstract class BaseRestController > handleTreeHasChildren(List> treeNodes,
+ Function, List> callback) {
+ if(CollUtil.isEmpty(treeNodes) || callback == null){
+ return treeNodes;
+ }
+
+ Set parentIds = Sets.newHashSet();
+ for (Tree treeNode : treeNodes) {
+ parentIds.add(Convert.toStr(treeNode.getId()));
+ }
+
+ // 数据排查是否存在下级
+ List hasChildrenList = callback.apply(parentIds);
+ if(CollUtil.isEmpty(hasChildrenList)){
+ hasChildrenList = ListUtil.empty();
+ }
+
+ // 字典
+ Map hasChildrenDict = Maps.newHashMap();
+ for (HasChildren hasChildren : hasChildrenList) {
+ if (hasChildren.getCount() != null && hasChildren.getCount() > 0) {
+ hasChildrenDict.put(hasChildren.getParentId(), true);
+ }
+ }
+
+ // 处理节点
+ this.handleTreeHasChildren(treeNodes, hasChildrenDict);
+
+ return treeNodes;
+ }
+
+ /**
+ * 处理 树节点是否 有子节点
+ * @param treeNodes 树节点
+ * @param hasChildrenDict 字典树
+ */
+ private void handleTreeHasChildren(List> treeNodes,
+ Map hasChildrenDict){
+
+ for (Tree treeNode : treeNodes) {
+ Boolean tmpFlag = hasChildrenDict.get(Convert.toStr(treeNode.getId()));
+ if (tmpFlag != null && tmpFlag) {
+ treeNode.putExtra(TreeConstants.IS_LEAF, false);
+ treeNode.putExtra(TreeConstants.HAS_CHILDREN, true);
+ }else {
+ treeNode.putExtra(TreeConstants.IS_LEAF, true);
+ treeNode.putExtra(TreeConstants.HAS_CHILDREN, false);
+ }
+
+ // 如果不为空 则继续递归处理
+ if(CollUtil.isNotEmpty(treeNode.getChildren())){
+ handleTreeHasChildren(treeNode.getChildren(), hasChildrenDict);
+ }
+ }
+ }
+
// =================================================
@PostConstruct
diff --git a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java
index b3eb5870..4514c32b 100644
--- a/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java
+++ b/opsli-modulars/opsli-modulars-system/src/main/java/org/opsli/modulars/system/menu/web/MenuRestController.java
@@ -25,7 +25,6 @@ import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -41,10 +40,10 @@ import org.opsli.common.annotation.EnableLog;
import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.constants.MenuConstants;
import org.opsli.common.constants.MyBatisConstants;
+import org.opsli.common.enums.DictType;
import org.opsli.common.utils.FieldUtil;
import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.base.controller.BaseRestController;
-import org.opsli.core.base.entity.HasChildren;
import org.opsli.core.general.StartPrint;
import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
@@ -63,7 +62,6 @@ import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
@@ -83,10 +81,6 @@ public class MenuRestController extends BaseRestController MenuConstants.MENU.equals(menuModel.getType()) &&
+ menuModelList.removeIf(
+ menuModel -> MenuConstants.MENU.equals(menuModel.getType()) &&
(StringUtils.isEmpty(menuModel.getComponent()) ||
StringUtils.isEmpty(menuModel.getUrl())
));
@@ -142,7 +137,8 @@ public class MenuRestController extends BaseRestController MenuConstants.MENU.equals(menuModel.getType()) &&
+ menuModelList.removeIf(
+ menuModel -> MenuConstants.MENU.equals(menuModel.getType()) &&
(StringUtils.isEmpty(menuModel.getComponent()) ||
StringUtils.isEmpty(menuModel.getUrl())
));
@@ -167,14 +163,9 @@ public class MenuRestController extends BaseRestController menuModelList;
if(StringUtils.isEmpty(parentId)){
menuModelList = Lists.newArrayList();
- parentId = VIRTUAL_TOTAL_NODE;
- MenuModel model = new MenuModel();
- model.setId(MenuConstants.GEN_ID);
- model.setMenuName("根节点");
- model.setHidden("0");
- model.setSortNo(-1);
- model.setType("1");
- model.setParentId(parentId);
+ // 生成根节点菜单
+ MenuModel model = getGenMenuModel();
+ parentId = model.getParentId();
menuModelList.add(model);
}else{
// 只查菜单
@@ -182,7 +173,7 @@ public class MenuRestController extends BaseRestController queryWrapper = queryBuilder.build();
queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId);
- queryWrapper.eq("type", "1");
+ queryWrapper.eq("type", MenuConstants.MENU);
// 如果传入ID 则不包含自身
if(StringUtils.isNotEmpty(id)){
@@ -200,7 +191,8 @@ public class MenuRestController extends BaseRestController> treeNodes = getMenuTrees(menuModelList, parentId,1);
// 处理是否包含子集
- this.handleTreeIsLeafByChoose(treeNodes);
+ super.handleTreeHasChildren(treeNodes,
+ (parentIds)-> IService.hasChildrenByChoose(parentIds));
return ResultVo.success(treeNodes);
}
@@ -216,14 +208,9 @@ public class MenuRestController extends BaseRestController menuModelList;
if(StringUtils.isEmpty(parentId)){
menuModelList = Lists.newArrayList();
- parentId = VIRTUAL_TOTAL_NODE;
- MenuModel model = new MenuModel();
- model.setId(MenuConstants.GEN_ID);
- model.setMenuName("根节点");
- model.setHidden("0");
- model.setSortNo(-1);
- model.setType("1");
- model.setParentId(parentId);
+ // 生成根节点菜单
+ MenuModel model = getGenMenuModel();
+ parentId = model.getParentId();
menuModelList.add(model);
}else{
QueryBuilder queryBuilder = new GenQueryBuilder<>();
@@ -238,7 +225,8 @@ public class MenuRestController extends BaseRestController> treeNodes = getMenuTrees(menuModelList, parentId,1);
// 处理是否包含子集
- this.handleTreeHasChildren(treeNodes);
+ super.handleTreeHasChildren(treeNodes,
+ (parentIds)-> IService.hasChildren(parentIds));
return ResultVo.success(treeNodes);
}
@@ -251,11 +239,9 @@ public class MenuRestController extends BaseRestController findMenuTreePage(HttpServletRequest request) {
-
QueryBuilder queryBuilder = new WebQueryBuilder<>(entityClazz,
request.getParameterMap());
-
// 获得菜单
List menuList = IService.findList(queryBuilder.build());
List menuModelList = WrapperUtil.transformInstance(menuList, MenuModel.class);
@@ -292,11 +278,8 @@ public class MenuRestController extends BaseRestController get(MenuModel model) {
if(model != null){
if(StringUtils.equals(MenuConstants.GEN_ID, model.getId())){
- model.setMenuName("根节点");
- model.setHidden("0");
- model.setSortNo(-1);
- model.setType("1");
- model.setParentId(VIRTUAL_TOTAL_NODE);
+ // 生成根节点菜单
+ model = getGenMenuModel();
}else{
// 如果系统内部调用 则直接查数据库
if (model.getIzApi() != null && model.getIzApi()){
@@ -589,72 +572,19 @@ public class MenuRestController extends BaseRestController> treeNodes) {
- if(CollUtil.isEmpty(treeNodes)){
- return;
- }
-
- Set parentIds = Sets.newHashSet();
- for (Tree treeNode : treeNodes) {
- parentIds.add(Convert.toStr(treeNode.getId()));
- }
-
- // 数据排查是否存在下级
- List hasChildrenList = IService.hasChildren(parentIds);
- if (CollUtil.isNotEmpty(hasChildrenList)) {
- Map tmp = Maps.newHashMap();
- for (HasChildren hasChildren : hasChildrenList) {
- if (hasChildren.getCount() != null && hasChildren.getCount() > 0) {
- tmp.put(hasChildren.getParentId(), true);
- }
- }
-
- for (Tree treeNode : treeNodes) {
- Boolean tmpFlag = tmp.get(Convert.toStr(treeNode.getId()));
- if (tmpFlag != null && tmpFlag) {
- treeNode.putExtra(HAS_CHILDREN, true);
- }
- }
- }
- }
-
-
- /**
- * 处理是否包含子集
- * @param treeNodes 树节点
- */
- private void handleTreeIsLeafByChoose(List> treeNodes) {
- if(CollUtil.isEmpty(treeNodes)){
- return;
- }
-
- Set parentIds = Sets.newHashSet();
- for (Tree treeNode : treeNodes) {
- parentIds.add(Convert.toStr(treeNode.getId()));
- }
-
- // 数据排查是否存在下级
- List hasChildrenList = IService.hasChildrenByChoose(parentIds);
- Map tmp = Maps.newHashMap();
- for (HasChildren hasChildren : hasChildrenList) {
- if (hasChildren.getCount() != null && hasChildren.getCount() > 0) {
- tmp.put(hasChildren.getParentId(), false);
- }
- }
-
- for (Tree treeNode : treeNodes) {
- Boolean tmpFlag = tmp.get(Convert.toStr(treeNode.getId()));
- if (tmpFlag == null || tmpFlag) {
- treeNode.putExtra(IS_LEAF, true);
- }else {
- treeNode.putExtra(IS_LEAF, false);
- }
- }
+ private MenuModel getGenMenuModel() {
+ MenuModel model = new MenuModel();
+ model.setId(MenuConstants.GEN_ID);
+ model.setMenuName("根菜单");
+ model.setHidden(DictType.NO_YES_NO.getValue());
+ model.setSortNo(-1);
+ model.setType(MenuConstants.MENU);
+ model.setParentId(VIRTUAL_TOTAL_NODE);
+ return model;
}
/**
diff --git a/opsli-starter/src/main/resources/application-dev.yaml b/opsli-starter/src/main/resources/application-dev.yaml
index 441ae2c6..880cd0dc 100644
--- a/opsli-starter/src/main/resources/application-dev.yaml
+++ b/opsli-starter/src/main/resources/application-dev.yaml
@@ -33,9 +33,9 @@ spring:
#primary: master
datasource:
master:
- url: jdbc:mysql://127.0.0.1:3306/opsli-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
- username: root
- password: 12345678
+ url: jdbc:mysql://10.0.0.28:3306/opsli-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
+ username: opsli-boot
+ password: asRtHGtxSZYGEtmJ
driver-class-name: com.mysql.cj.jdbc.Driver
# 多数据源配置
#slave-datasource: