parent
9ab2bacf42
commit
44f3c76c78
@ -0,0 +1,18 @@ |
|||||||
|
.treeTable-empty { |
||||||
|
width: 20px; |
||||||
|
display: inline-block; |
||||||
|
} |
||||||
|
|
||||||
|
.treeTable-icon { |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
|
||||||
|
.treeTable-icon .layui-icon-triangle-d:before { |
||||||
|
content: "\e623"; |
||||||
|
} |
||||||
|
|
||||||
|
.treeTable-icon.open .layui-icon-triangle-d:before { |
||||||
|
content: "\e625"; |
||||||
|
background-color: transparent; |
||||||
|
} |
||||||
|
|
@ -0,0 +1,206 @@ |
|||||||
|
layui.define(['layer', 'table'], function (exports) { |
||||||
|
var $ = layui.jquery; |
||||||
|
var layer = layui.layer; |
||||||
|
var table = layui.table; |
||||||
|
|
||||||
|
var treetable = { |
||||||
|
// 渲染树形表格
|
||||||
|
render: function (param) { |
||||||
|
// 检查参数
|
||||||
|
if (!treetable.checkParam(param)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
// 获取数据
|
||||||
|
if (param.data) { |
||||||
|
treetable.init(param, param.data); |
||||||
|
} else { |
||||||
|
$.getJSON(param.url, param.where, function (res) { |
||||||
|
treetable.init(param, res.data); |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
// 渲染表格
|
||||||
|
init: function (param, data) { |
||||||
|
var mData = []; |
||||||
|
var doneCallback = param.done; |
||||||
|
var tNodes = data; |
||||||
|
// 补上id和pid字段
|
||||||
|
for (var i = 0; i < tNodes.length; i++) { |
||||||
|
var tt = tNodes[i]; |
||||||
|
if (!tt.id) { |
||||||
|
if (!param.treeIdName) { |
||||||
|
layer.msg('参数treeIdName不能为空', {icon: 5}); |
||||||
|
return; |
||||||
|
} |
||||||
|
tt.id = tt[param.treeIdName]; |
||||||
|
} |
||||||
|
if (!tt.pid) { |
||||||
|
if (!param.treePidName) { |
||||||
|
layer.msg('参数treePidName不能为空', {icon: 5}); |
||||||
|
return; |
||||||
|
} |
||||||
|
tt.pid = tt[param.treePidName]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 对数据进行排序
|
||||||
|
var sort = function (s_pid, data) { |
||||||
|
for (var i = 0; i < data.length; i++) { |
||||||
|
if (data[i].pid == s_pid) { |
||||||
|
var len = mData.length; |
||||||
|
if (len > 0 && mData[len - 1].id == s_pid) { |
||||||
|
mData[len - 1].isParent = true; |
||||||
|
} |
||||||
|
mData.push(data[i]); |
||||||
|
sort(data[i].id, data); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
sort(param.treeSpid, tNodes); |
||||||
|
|
||||||
|
// 重写参数
|
||||||
|
param.url = undefined; |
||||||
|
param.data = mData; |
||||||
|
param.page = { |
||||||
|
count: param.data.length, |
||||||
|
limit: param.data.length |
||||||
|
}; |
||||||
|
param.cols[0][param.treeColIndex].templet = function (d) { |
||||||
|
var mId = d.id; |
||||||
|
var mPid = d.pid; |
||||||
|
var isDir = d.isParent; |
||||||
|
var emptyNum = treetable.getEmptyNum(mPid, mData); |
||||||
|
var iconHtml = ''; |
||||||
|
for (var i = 0; i < emptyNum; i++) { |
||||||
|
iconHtml += '<span class="treeTable-empty"></span>'; |
||||||
|
} |
||||||
|
if (isDir) { |
||||||
|
iconHtml += '<i class="layui-icon layui-icon-triangle-d"></i> <i class="layui-icon layui-icon-layer"></i>'; |
||||||
|
} else { |
||||||
|
iconHtml += '<i class="layui-icon layui-icon-file"></i>'; |
||||||
|
} |
||||||
|
iconHtml += ' '; |
||||||
|
var ttype = isDir ? 'dir' : 'file'; |
||||||
|
var vg = '<span class="treeTable-icon open" lay-tid="' + mId + '" lay-tpid="' + mPid + '" lay-ttype="' + ttype + '">'; |
||||||
|
return vg + iconHtml + d[param.cols[0][param.treeColIndex].field] + '</span>' |
||||||
|
}; |
||||||
|
|
||||||
|
param.done = function (res, curr, count) { |
||||||
|
$(param.elem).next().addClass('treeTable'); |
||||||
|
$('.treeTable .layui-table-page').css('display', 'none'); |
||||||
|
$(param.elem).next().attr('treeLinkage', param.treeLinkage); |
||||||
|
// 绑定事件换成对body绑定
|
||||||
|
/*$('.treeTable .treeTable-icon').click(function () { |
||||||
|
treetable.toggleRows($(this), param.treeLinkage); |
||||||
|
});*/ |
||||||
|
if (param.treeDefaultClose) { |
||||||
|
treetable.foldAll(param.elem); |
||||||
|
} |
||||||
|
if (doneCallback) { |
||||||
|
doneCallback(res, curr, count); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
// 渲染表格
|
||||||
|
table.render(param); |
||||||
|
}, |
||||||
|
// 计算缩进的数量
|
||||||
|
getEmptyNum: function (pid, data) { |
||||||
|
var num = 0; |
||||||
|
if (!pid) { |
||||||
|
return num; |
||||||
|
} |
||||||
|
var tPid; |
||||||
|
for (var i = 0; i < data.length; i++) { |
||||||
|
if (pid == data[i].id) { |
||||||
|
num += 1; |
||||||
|
tPid = data[i].pid; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return num + treetable.getEmptyNum(tPid, data); |
||||||
|
}, |
||||||
|
// 展开/折叠行
|
||||||
|
toggleRows: function ($dom, linkage) { |
||||||
|
var type = $dom.attr('lay-ttype'); |
||||||
|
if ('file' == type) { |
||||||
|
return; |
||||||
|
} |
||||||
|
var mId = $dom.attr('lay-tid'); |
||||||
|
var isOpen = $dom.hasClass('open'); |
||||||
|
if (isOpen) { |
||||||
|
$dom.removeClass('open'); |
||||||
|
} else { |
||||||
|
$dom.addClass('open'); |
||||||
|
} |
||||||
|
$dom.closest('tbody').find('tr').each(function () { |
||||||
|
var $ti = $(this).find('.treeTable-icon'); |
||||||
|
var pid = $ti.attr('lay-tpid'); |
||||||
|
var ttype = $ti.attr('lay-ttype'); |
||||||
|
var tOpen = $ti.hasClass('open'); |
||||||
|
if (mId == pid) { |
||||||
|
if (isOpen) { |
||||||
|
$(this).hide(); |
||||||
|
if ('dir' == ttype && tOpen == isOpen) { |
||||||
|
$ti.trigger('click'); |
||||||
|
} |
||||||
|
} else { |
||||||
|
$(this).show(); |
||||||
|
if (linkage && 'dir' == ttype && tOpen == isOpen) { |
||||||
|
$ti.trigger('click'); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
// 检查参数
|
||||||
|
checkParam: function (param) { |
||||||
|
if (!param.treeSpid && param.treeSpid != 0) { |
||||||
|
layer.msg('参数treeSpid不能为空', {icon: 5}); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (!param.treeColIndex && param.treeColIndex != 0) { |
||||||
|
layer.msg('参数treeColIndex不能为空', {icon: 5}); |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
}, |
||||||
|
// 展开所有
|
||||||
|
expandAll: function (dom) { |
||||||
|
$(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () { |
||||||
|
var $ti = $(this).find('.treeTable-icon'); |
||||||
|
var ttype = $ti.attr('lay-ttype'); |
||||||
|
var tOpen = $ti.hasClass('open'); |
||||||
|
if ('dir' == ttype && !tOpen) { |
||||||
|
$ti.trigger('click'); |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
// 折叠所有
|
||||||
|
foldAll: function (dom) { |
||||||
|
$(dom).next('.treeTable').find('.layui-table-body tbody tr').each(function () { |
||||||
|
var $ti = $(this).find('.treeTable-icon'); |
||||||
|
var ttype = $ti.attr('lay-ttype'); |
||||||
|
var tOpen = $ti.hasClass('open'); |
||||||
|
if ('dir' == ttype && tOpen) { |
||||||
|
$ti.trigger('click'); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
layui.link(layui.cache.base + 'treetable-lay/treetable.css'); |
||||||
|
|
||||||
|
// 给图标列绑定事件
|
||||||
|
$('body').on('click', '.treeTable .treeTable-icon', function () { |
||||||
|
var treeLinkage = $(this).parents('.treeTable').attr('treeLinkage'); |
||||||
|
if ('true' == treeLinkage) { |
||||||
|
treetable.toggleRows($(this), true); |
||||||
|
} else { |
||||||
|
treetable.toggleRows($(this), false); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
exports('treetable', treetable); |
||||||
|
}); |
@ -0,0 +1,53 @@ |
|||||||
|
lib.config({ |
||||||
|
base: '../../assets/lib/layuiext/module/' |
||||||
|
}).extend({ |
||||||
|
treetable: 'treetable-lay/treetable' |
||||||
|
}).use(['element', 'table', 'form', 'treetable'], function () { |
||||||
|
var layer = layui.layer; |
||||||
|
var form = layui.form; |
||||||
|
var treetable = layui.treetable; |
||||||
|
var serverTable; |
||||||
|
|
||||||
|
// 渲染表格
|
||||||
|
var renderTable = function () { |
||||||
|
layer.load(2); |
||||||
|
serverTable = treetable.render({ |
||||||
|
treeColIndex: 1, |
||||||
|
treeSpid: 0, |
||||||
|
treeIdName: 'id', |
||||||
|
treePidName: 'parentId', |
||||||
|
treeDefaultClose: true, |
||||||
|
treeLinkage: false, |
||||||
|
elem: '#treeTable', |
||||||
|
url: ApiUtil.createUrl('service.instance.list'), |
||||||
|
page: false, |
||||||
|
cols: [[ |
||||||
|
{type: 'numbers'}, |
||||||
|
{field: 'name', title: '服务名称', width: 200}, |
||||||
|
{field: 'instanceId', title: 'instanceId', width: 220}, |
||||||
|
{field: 'ipAddr', title: 'IP地址', width: 150}, |
||||||
|
{field: 'serverPort', title: '端口号', width: 100}, |
||||||
|
{field: 'status', title: 'status', width: 100}, |
||||||
|
{field: 'updateTime', title: '最后更新时间', width: 150}, |
||||||
|
{fixed: 'right', templet: '#optCol', title: '操作', width: 200} |
||||||
|
]], |
||||||
|
done: function () { |
||||||
|
layer.closeAll('loading'); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
renderTable(); |
||||||
|
|
||||||
|
|
||||||
|
form.on('submit(searchFilter)', function(data){ |
||||||
|
var param = data.field; |
||||||
|
serverTable.reload({ |
||||||
|
where: { |
||||||
|
data: JSON.stringify(param) |
||||||
|
} |
||||||
|
}) |
||||||
|
return false; |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
@ -0,0 +1,52 @@ |
|||||||
|
package com.gitee.sop.adminserver.api.service.result; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.annotation.JSONField; |
||||||
|
import com.gitee.easyopen.doc.annotation.ApiDocField; |
||||||
|
import lombok.Data; |
||||||
|
import org.apache.commons.lang.StringUtils; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class ServiceInfoVo { |
||||||
|
@ApiDocField(description = "id") |
||||||
|
private Integer id; |
||||||
|
|
||||||
|
@ApiDocField(description = "服务名称") |
||||||
|
private String name; |
||||||
|
|
||||||
|
@ApiDocField(description = "instanceId") |
||||||
|
private String instanceId; |
||||||
|
|
||||||
|
@ApiDocField(description = "ip") |
||||||
|
private String ipAddr; |
||||||
|
|
||||||
|
@ApiDocField(description = "端口") |
||||||
|
private String serverPort; |
||||||
|
|
||||||
|
@ApiDocField(description = "status") |
||||||
|
private String status; |
||||||
|
|
||||||
|
@ApiDocField(description = "statusPageUrl") |
||||||
|
private String statusPageUrl; |
||||||
|
|
||||||
|
@ApiDocField(description = "healthCheckUrl") |
||||||
|
private String healthCheckUrl; |
||||||
|
|
||||||
|
@ApiDocField(description = "最后更新时间") |
||||||
|
private String lastUpdatedTimestamp; |
||||||
|
|
||||||
|
@ApiDocField(description = "parentId") |
||||||
|
private Integer parentId; |
||||||
|
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss") |
||||||
|
public Date getUpdateTime() { |
||||||
|
if (StringUtils.isBlank(lastUpdatedTimestamp)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return new Date(Long.valueOf(lastUpdatedTimestamp)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package com.gitee.sop.adminserver.bean; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class EurekaApplication { |
||||||
|
private String name; |
||||||
|
private List<EurekaInstance> instance; |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package com.gitee.sop.adminserver.bean; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class EurekaApplications { |
||||||
|
private List<EurekaApplication> application; |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
package com.gitee.sop.adminserver.bean; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class EurekaApps { |
||||||
|
private EurekaApplications applications; |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package com.gitee.sop.adminserver.bean; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
import org.springframework.util.CollectionUtils; |
||||||
|
|
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
public class EurekaInstance { |
||||||
|
private String instanceId; |
||||||
|
private String ipAddr; |
||||||
|
private Map<String, Object> port; |
||||||
|
|
||||||
|
private String status; |
||||||
|
private String statusPageUrl; |
||||||
|
private String healthCheckUrl; |
||||||
|
private String lastUpdatedTimestamp; |
||||||
|
|
||||||
|
public String fetchPort() { |
||||||
|
if (CollectionUtils.isEmpty(port)) { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
return String.valueOf(port.getOrDefault("$", "")); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package com.gitee.sop.adminserver.bean; |
||||||
|
|
||||||
|
/** |
||||||
|
* https://github.com/Netflix/eureka/wiki/Eureka-REST-operations
|
||||||
|
* @author tanghc |
||||||
|
*/ |
||||||
|
public enum EurekaUri { |
||||||
|
|
||||||
|
/** Query for all instances */ |
||||||
|
QUERY_APPS("/apps"), |
||||||
|
; |
||||||
|
String uri; |
||||||
|
|
||||||
|
EurekaUri(String uri) { |
||||||
|
this.uri = uri; |
||||||
|
} |
||||||
|
|
||||||
|
public String getUri() { |
||||||
|
return uri; |
||||||
|
}} |
Loading…
Reference in new issue