diff --git a/src/main/java/com/maxbill/base/bean/ZTreeBean.java b/src/main/java/com/maxbill/base/bean/ZTreeBean.java index f394800881c72ce1d3e58d5050e77e5edb60cae9..85a78b81bc7f627531c71552f7b67d1d89a64390 100644 --- a/src/main/java/com/maxbill/base/bean/ZTreeBean.java +++ b/src/main/java/com/maxbill/base/bean/ZTreeBean.java @@ -1,9 +1,17 @@ package com.maxbill.base.bean; import com.alibaba.fastjson.annotation.JSONField; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; @Data +@Builder +@NoArgsConstructor +@AllArgsConstructor public class ZTreeBean { private String id; @@ -28,8 +36,7 @@ public class ZTreeBean { @JSONField(name = "isParent") private boolean isParent; - public ZTreeBean() { - } + private List children; public ZTreeBean(String id, String name) { this.id = id; diff --git a/src/main/java/com/maxbill/base/controller/DataClusterController.java b/src/main/java/com/maxbill/base/controller/DataClusterController.java index 055e5fb0c8ce4a033bf9805ea3eea904914ca893..32f89c3bb0c980dbe7f10dc934270fb0dd9cef4f 100644 --- a/src/main/java/com/maxbill/base/controller/DataClusterController.java +++ b/src/main/java/com/maxbill/base/controller/DataClusterController.java @@ -14,10 +14,7 @@ import redis.clients.jedis.JedisCluster; import redis.clients.jedis.JedisPool; import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import static com.maxbill.base.bean.ResultInfo.*; @@ -54,7 +51,7 @@ public class DataClusterController { } ZTreeBean ztreeBean = new ZTreeBean(); ztreeBean.setId(KeyUtil.getUUIDKey()); - ztreeBean.setName("全部集群节点的KEY" + "(" + total + ")"); + ztreeBean.setName("全部集群节点的KEY" + " (" + total + ")"); ztreeBean.setPattern(""); ztreeBean.setParent(true); ztreeBean.setCount(total); @@ -90,7 +87,7 @@ public class DataClusterController { } ZTreeBean ztreeBean = new ZTreeBean(); ztreeBean.setId(KeyUtil.getUUIDKey()); - ztreeBean.setName("全部集群节点的KEY" + "(" + total + ")"); + ztreeBean.setName("全部集群节点的KEY" + " (" + total + ")"); ztreeBean.setPattern(pattern); ztreeBean.setParent(true); ztreeBean.setCount(total); @@ -106,7 +103,7 @@ public class DataClusterController { } - public String treeData(String id, int page, String pattern) { + public String treeData(String pid, int page, String pattern) { try { JedisCluster cluster = DataUtil.getJedisClusterObject(); if (null != cluster) { @@ -116,44 +113,37 @@ public class DataClusterController { List nodeList = ClusterUtil.getClusterNode(DataUtil.getCurrentOpenConnect()); Map masterNode = ClusterUtil.getMasterNode(nodeList); Map clusterNodes = cluster.getClusterNodes(); - List treeList = new ArrayList<>(); - List keyList = new ArrayList<>(); - long count = 0L; + List keyList = new LinkedList<>(); for (String nk : clusterNodes.keySet()) { if (masterNode.keySet().contains(nk)) { Jedis jedis = clusterNodes.get(nk).getResource(); keyList.addAll(jedis.keys(pattern)); - count = count + jedis.keys(pattern).size(); RedisUtil.closeJedis(jedis); } } - int startIndex = (page - 1) * 50; - int endIndex = page * 50; - if (endIndex > count) { - endIndex = (int) count; + // 按字母排序 + Collections.sort(keyList); + + // 分页返回 + int startIndex = (page - 1) * 1000; + int endIndex = page * 1000; + if (endIndex > keyList.size()) { + endIndex = keyList.size(); } - keyList = keyList.subList(startIndex, endIndex); - if (!keyList.isEmpty()) { - for (String key : keyList) { - ZTreeBean zTreeBean = new ZTreeBean(); - zTreeBean.setId(KeyUtil.getUUIDKey()); - zTreeBean.setPId(id); - zTreeBean.setName(key); - zTreeBean.setParent(false); - zTreeBean.setIcon("../image/data-01.png"); - treeList.add(zTreeBean); - } + List treeList = new LinkedList<>(); + for (String key : keyList.subList(startIndex, endIndex)) { + RedisUtil.groupRecursiveLoad(treeList, key, null, pid); } return getOkByJson(treeList); } else { return disconnect(); } } catch (Exception e) { + e.printStackTrace(); return exception(e); } } - public String keysData(String key, String order) { try { JedisCluster cluster = DataUtil.getJedisClusterObject(); diff --git a/src/main/java/com/maxbill/tool/ClusterUtil.java b/src/main/java/com/maxbill/tool/ClusterUtil.java index 3bbf37ebf6c4b990ffc2b3aa4ca8880fbc888b58..00e5b92aabc8dc037f825e658b8be2a44900ebd6 100644 --- a/src/main/java/com/maxbill/tool/ClusterUtil.java +++ b/src/main/java/com/maxbill/tool/ClusterUtil.java @@ -221,6 +221,13 @@ public class ClusterUtil { jedisCluster.set(newKey, strs); break; } + + // 设置过期时间 + Long ttl = jedisCluster.ttl(oldKey); + if (ttl > -1) { + jedisCluster.expire(newKey, ttl.intValue()); + } + jedisCluster.del(oldKey); } /** diff --git a/src/main/java/com/maxbill/tool/RedisUtil.java b/src/main/java/com/maxbill/tool/RedisUtil.java index e5b9234e3ea7f3ee39065df5dcdd1a2160313195..237d9344f43143507db0a2ef6572a76c5e6ed4df 100644 --- a/src/main/java/com/maxbill/tool/RedisUtil.java +++ b/src/main/java/com/maxbill/tool/RedisUtil.java @@ -361,7 +361,6 @@ public class RedisUtil { * 按条件获取分页数据 */ public static List getKeyTree(Jedis jedis, int index, int page, String pid, String pattern) { - List treeList = new ArrayList<>(); long startTime = System.currentTimeMillis(); jedis.select(index); if (StringUtils.isEmpty(pattern)) { @@ -370,30 +369,78 @@ public class RedisUtil { Set keySet = jedis.keys(pattern); long endTime = System.currentTimeMillis(); log.info("getKeyTree查询耗时:" + (endTime - startTime)); - ZTreeBean zTreeBean = null; - if (null != keySet) { - for (String key : keySet) { - zTreeBean = new ZTreeBean(); - zTreeBean.setId(KeyUtil.getUUIDKey()); - zTreeBean.setPId(pid); - zTreeBean.setName(key); - zTreeBean.setParent(false); - zTreeBean.setIndex(index); - zTreeBean.setIcon("../image/data-01.png"); - treeList.add(zTreeBean); - } + + // 排序 + List keyList = new LinkedList<>(keySet); + Collections.sort(keyList); + + // 分页返回 + int startIndex = (page - 1) * 1000; + int endIndex = page * 1000; + if (endIndex > keyList.size()) { + endIndex = keyList.size(); } - //封装返回数据 - int startIndex = (page - 1) * 50; - int endIndex = page * 50; - long count = RedisUtil.getKeysCount(jedis, index, pattern); - if (endIndex > count) { - endIndex = (int) count; + List treeList = new ArrayList<>(); + for (String key : keyList.subList(startIndex, endIndex)) { + groupRecursiveLoad(treeList, key, null, pid); } - treeList = treeList.subList(startIndex, endIndex); return treeList; } + + /** + * 分组递归加载节点 + * + * @param nodes + * @param key + * @param pref + * @param pid + */ + public static void groupRecursiveLoad(List nodes, String key, String pref, String pid) { + String thisKey = new String(key); + if (pref != null && key.startsWith(pref)) { + thisKey = thisKey.substring(pref.length()); + } + + /** 普通节点类型:直接添加 */ + String[] metas = thisKey.split(":"); + if (metas.length == 1) { + ZTreeBean node = ZTreeBean.builder() + .id(KeyUtil.getUUIDKey()) + .pId(pid) + .name(key) + .isParent(false) + .icon("../image/data-01.png") + .build(); + nodes.add(node); + return; + } + + /** 对象节点类型:递归添加(Object:Field:Field) */ + // 1、先查找已存在的上级节点 + List children = null; + for (ZTreeBean parent : nodes) { + if (parent.isParent() && parent.getName().equals(metas[0])) { + children = parent.getChildren(); + break; + } + } + // 2、不存在上级时:创建上级节点 + String id = KeyUtil.getUUIDKey(); + if (children == null) { + ZTreeBean parent = ZTreeBean.builder() + .id(id) + .pId(pid) + .name(metas[0]) + .isParent(true) + .children(children = new LinkedList<>()) + .build(); + nodes.add(parent); + } + // 3、递归——添加children + groupRecursiveLoad(children, key, (pref == null ? "" : pref) + metas[0] + ":", id); + } + /** * 按条件获取分页数据(scan) */ @@ -406,13 +453,13 @@ public class RedisUtil { } //计算获取的数据量 long pageSize; - long currSize = page * 50; - long currScan = (page - 1) * 50; + long currSize = page * 1000; + long currScan = (page - 1) * 1000; long keysSize = getKeysCount(jedis, index, pattern); if (keysSize - currSize < 0) { pageSize = currSize - keysSize; } else { - pageSize = 50; + pageSize = 1000; } //scan数据查询 ScanParams scanParams = new ScanParams(); diff --git a/src/main/resources/page/data-cluster.html b/src/main/resources/page/data-cluster.html index 7f786c1a67387b3c92d0aff423af9acdc4ec4da0..2631fa7e89f014a73c2b106d47ed41c53f6d12e6 100644 --- a/src/main/resources/page/data-cluster.html +++ b/src/main/resources/page/data-cluster.html @@ -99,36 +99,36 @@
-
-
+
+ +
+
-
- -
- +
-
+
diff --git a/src/main/resources/page/data-singles.html b/src/main/resources/page/data-singles.html index 20573de67ea89fa680f3b5317639c171981f3214..269f2f09664c0aed8ab7baa5e347094d18d4ba05 100644 --- a/src/main/resources/page/data-singles.html +++ b/src/main/resources/page/data-singles.html @@ -99,36 +99,36 @@
-
- +
+
+
-
+ +
-
- -
- +
-
+
diff --git a/src/main/resources/script/data-cluster.js b/src/main/resources/script/data-cluster.js index 9a8d82bd51b1fee4c1e6cd200196544180b9d20b..e5728d0ac007d40eb132b3a13561c30dcdc7d0be 100644 --- a/src/main/resources/script/data-cluster.js +++ b/src/main/resources/script/data-cluster.js @@ -141,7 +141,9 @@ function ztreeOnClick(event, treeId, treeNode) { function ztreeOnExpand(event, treeId, treeNode) { if (treeNode.isParent) { currNode0 = treeNode; - loadDbData(treeNode, treeNode.pattern); + // 如果tree节点携带子节点,则不再请求后台获取 + if (!treeNode.children || treeNode.children == null || treeNode.children.length == 0) + loadDbData(treeNode, treeNode.pattern); } } @@ -268,7 +270,7 @@ function loadDbData(node, pattern) { var zTree = $.fn.zTree.getZTreeObj('keyTree'); zTree.removeChildNodes(node); zTree.addNodes(node, 0, data.data); - zTree.expandAll(true); + // zTree.expandAll(true); } else { layer.alert(data.msgs, { skin: 'layui-layer-lan', @@ -598,7 +600,16 @@ function getEditView(type, data) { view += ''; break; case "string": - view += ''; + var isjson = false; + var result = ""; + try { + result = JSON.stringify(JSON.parse(data), null, 2); + layer.msg("检测数据为JSON格式"); + isjson = true; + } catch (e) { + result = data; + } + view += ''; view += ''; break; @@ -612,9 +623,23 @@ function updateStr() { layer.msg("请选择要操作的KEY!"); return false; } + + var str = null; + try { + var data = JSON.parse($("#currVal").val()); + str = JSON.stringify(data); + } catch (err) { + if ($("#currVal").attr("isjson") == 'true') { + layer.msg("修改失败!不符合JSON格式请检查..."); + return; + } + str = $("#currVal").val() + } + layer.load(2); - var json = dataClusterRouter.updateStr(currNode1.name, $("#currVal").val()); + var json = dataClusterRouter.updateStr(currNode1.name, str); var data = JSON.parse(json); + layer.closeAll('loading'); if (data.code === 200) { getKeysInfo(""); diff --git a/src/main/resources/script/data-singles.js b/src/main/resources/script/data-singles.js index 60f7f3c5069529d6a5661ddbbebc3a1f8d519bc2..61d224cfe16ecdd814ddb72308b49441dd3a8330 100644 --- a/src/main/resources/script/data-singles.js +++ b/src/main/resources/script/data-singles.js @@ -155,7 +155,10 @@ function ztreeOnExpand(event, treeId, treeNode) { } }); currNode0 = treeNode; - loadDbData(treeNode, treeNode.pattern); + + // 如果tree节点携带子节点,则不再请求后台获取 + if (!treeNode.children || treeNode.children == null || treeNode.children.length == 0) + loadDbData(treeNode, treeNode.pattern); checkedOnTree(treeNode.index); } @@ -308,7 +311,7 @@ function loadDbData(node, pattern) { var zTree = $.fn.zTree.getZTreeObj('keyTree' + node.index); zTree.removeChildNodes(node); zTree.addNodes(node, 0, data.data); - zTree.expandAll(true); + // zTree.expandAll(true); } else { layer.alert(data.msgs, { skin: 'layui-layer-lan', @@ -637,7 +640,17 @@ function getEditView(type, data) { view += ''; break; case "string": - view += ''; + var isjson = false; + var result = ""; + try { + result = JSON.stringify(JSON.parse(data), null, 2); + layer.msg("检测数据为JSON格式"); + isjson = true; + } catch (e) { + result = data; + } + + view += ''; view += ''; break; @@ -651,8 +664,21 @@ function updateStr() { layer.msg("请选择要操作的KEY!"); return false; } + + var str = null; + try { + var data = JSON.parse($("#currVal").val()); + str = JSON.stringify(data); + } catch (err) { + if ($("#currVal").attr("isjson") == "true") { + layer.msg("修改失败!不符合JSON格式请检查..."); + return; + } + str = $("#currVal").val() + } + layer.load(2); - var json = dataSinglesRouter.updateStr(currNode0.index, currNode1.name, $("#currVal").val()); + var json = dataSinglesRouter.updateStr(currNode0.index, currNode1.name, str); var data = JSON.parse(json); layer.closeAll('loading'); if (data.code === 200) {