Files
yakpanel-core/YakPanel/static/js/term.js

1236 lines
49 KiB
JavaScript
Raw Normal View History

2026-04-07 02:04:22 +05:30
function Terms(el,config){
if(typeof config == "undefined") config = {};
this.el = el;
this.id = config.ssh_info.id || '';
this.bws = null; //websocket对象
this.route ='/webssh'; // 访问的方法
this.term =null; //term对象
this.info =null; // 请求数据
this.last_body =null;
this.fontSize =15; //终端字体大小
this.ssh_info = config.ssh_info;
this.run();
}
Terms.prototype = {
// websocket持久化连接
connect:function(callback){
var that = this;
// 判断当前websocket连接是否存在
if(!this.bws || this.bws.readyState == 3 || this.bws.readyState == 2){
this.bws = new WebSocket((window.location.protocol === 'http:' ? 'ws://' : 'wss://') + window.location.host + this.route);
this.bws.addEventListener('message',function(ev){that.on_message(ev)});
this.bws.addEventListener('close',function(ev){that.on_close(ev)});
this.bws.addEventListener('error',function(ev){that.on_error(ev)});
this.bws.addEventListener('open',function(ev){that.on_open(ev)});
if(callback) callback(this.bws)
}
},
//连接服务器成功
on_open:function(ws_event){
var http_token = $("#request_token_head").attr('token');
this.send(JSON.stringify({'x-http-token':http_token}))
this.send(JSON.stringify(this.ssh_info || {}))
this.term.FitAddon.fit();
this.resize({cols:this.term.cols, rows:this.term.rows});
},
//服务器消息事件
on_message: function (ws_event){
result= ws_event.data;
if(!result) return;
that = this;
if ((result.indexOf("@127.0.0.1:") != -1 || result.indexOf("@localhost:") != -1) && result.indexOf('Authentication failed') != -1) {
that.term.write(result);
host_trem.localhost_login_form(result);
that.close();
return;
}
if(result.length > 1 && that.last_body === false){
that.last_body = true;
}
that.term.write(result);
that.set_term_icon(1);
if (result == '\r\n登出\r\n' || result == '登出\r\n' || result == '\r\nlogout\r\n' || result == 'logout\r\n') {
that.close();
that.bws = null;
}
},
//websocket关闭事件
on_close: function (ws_event) {
this.set_term_icon(0);
this.bws = null;
},
/**
* @name 设置终端标题状态
* @author chudong<2020-08-10>
* @param {number} status 终端状态
* @return void
*/
set_term_icon:function(status){
var icon_list = ['icon-warning','icon-sucess','icon-info'];
if(status == 1){
if($("[data-id='"+ this.id +"']").attr("class").indexOf('active') == -1){
status = 2;
}
}
$("[data-id='"+ this.id +"']").find('.icon').removeAttr('class').addClass(icon_list[status]+' icon');
if(status == 2){
that = this;
setTimeout(function(){
$("[data-id='"+ that.id +"']").find('.icon').removeAttr('class').addClass(icon_list[1]+' icon');
},200);
}
},
//websocket错误事件
on_error: function (ws_event) {
if(ws_event.target.readyState === 3){
// var msg = '错误: 无法创建WebSocket连接请在面板设置页面关闭【开发者模式】';
// layer.msg(msg,{time:5000})
// if(Term.state === 3) return
// Term.term.write(msg)
// Term.state = 3;
}else{
console.log(ws_event)
}
},
//发送数据
//@param event 唯一事件名称
//@param data 发送的数据
//@param callback 服务器返回结果时回调的函数,运行完后将被回收
send: function (data, num) {
var that = this;
//如果没有连接,则尝试连接服务器
if (!this.bws || this.bws.readyState == 3 || this.bws.readyState == 2) {
this.connect();
}
//判断当前连接状态,如果!=1则100ms后尝试重新发送
if (this.bws.readyState === 1) {
this.bws.send(data);
} else {
if(this.state === 3) return;
if (!num) num = 0;
if (num < 5) {
num++;
setTimeout(function () { that.send(data, num++); }, 100)
}
}
},
//关闭连接
close: function () {
this.bws.close();
this.set_term_icon(0);
},
resize: function (size){
if(this.bws){
size['resize'] = 1;
this.send(JSON.stringify(size));
}
},
run: function (ssh_info) {
var that = this;
this.term = new Terminal({fontSize:this.fontSize, screenKeys: true, useStyle: true });
this.term.setOption('cursorBlink', true);
this.last_body = false;
this.term.open($(this.el)[0]);
this.term.FitAddon = new FitAddon.FitAddon();
this.term.loadAddon(this.term.FitAddon);
this.term.WebLinksAddon = new WebLinksAddon.WebLinksAddon()
this.term.loadAddon(this.term.WebLinksAddon)
if (ssh_info) this.ssh_info = ssh_info
this.connect();
that.term.onData(function (data) {
try {
that.bws.send(data)
} catch (e) {
that.term.write('\r\nConnection lost, trying to connect again!\r\n')
that.connect()
}
});
this.term.focus();
}
}
var host_trem = {
host_term:{},
host_list:[],
command_list:[],
sort_time:null,
is_full:false,
command_form:{
title:'',
shell:'',
},
host_form:{
host:'',
port:'22', //默认端口22
username:'root',
password:'',
pkey: '',
ps: ''
},
init:function(){
var that = this;
Object.defineProperty(host_trem,'is_full',{
get:function(val){
return val;
},
set:function(newValue) {
if(newValue){
$('body').addClass('full_term_view');
var win = $(window)[0],win_width = win.innerHeight,win_height = win.innerHeight;
$('.main-content .safe').height(win_height);
$('#term_box_view,.term_tootls').height(win_height);
$('.tootls_host_list').height((win_height - 80) * .75);
$('.tootls_commonly_list').height((win_height - 80) * .25);
$('.tab_tootls .glyphicon').removeClass('glyphicon-resize-full').addClass('glyphicon-resize-small').attr('title','Exit full screen');
}else{
$('body').removeClass('full_term_view');
$('.tab_tootls .glyphicon').removeClass('glyphicon-resize-small').addClass('glyphicon-resize-full').attr('title','Full Screen');
}
}
});
document.onkeydown = function(e){
e = e || window.event;
if ((e.metaKey && e.keyCode == 82) || e.keyCode == 116){
return false;
}
if(that.is_full && e.keyCode == 27){
return false;
}
}
//本地存储
var _tool_status = localStorage.getItem("tool_status");
_tool_host_height = localStorage.getItem("hostHeight"),
_tool_commonly_height = localStorage.getItem("commonlyHeight");
if(_tool_commonly_height <= 100 )_tool_commonly_height=100;
$(window).resize(function(ev){
that.on_resize(that);
});
$('.tab_tootls').on('click','.glyphicon-resize-full',function(){
$(this).removeClass('glyphicon-resize-full').addClass('glyphicon-resize-small').attr('title','Exit full Screen');
$('body').addClass('full_term_view');
that.requestFullScreen();
});
$('.tab_tootls').on('click','.glyphicon-resize-small',function(){
$(this).removeClass('glyphicon-resize-small').addClass('glyphicon-resize-full').attr('title','Full Screen');
$('body').removeClass('full_term_view');
that.exitFullscreen();
});
$(document).ready(function (e) {
var win = $(window)[0],win_width = win.innerHeight,win_height = win.innerHeight,host_commonly = win_height - 185;
$('.main-content .safe').height(win_height - 105);
$('#term_box_view,.term_tootls').height(win_height - 105);
if(_tool_host_height !=0&&_tool_commonly_height !=0){
$(".tootls_host_list").css("height",_tool_host_height+"px"),
$(".tootls_commonly_list").css("height", _tool_commonly_height+"px");
}else{
$('.tootls_host_list').height(host_commonly * .75);
$('.tootls_commonly_list').height(host_commonly * .25);
}
that.open_term_view();
});
// 添加服务器信息
$('.addServer').on('click',function(){
that.editor_host_view();
});
// 切换服务器终端视图
$('.term_item_tab .list').on('click','span.item',function(ev){
var index = $(this).index(),data = $(this).data();
if($(this).hasClass('addServer')){
}else if($(this).hasClass('tab_tootls')){
}else{
$(this).addClass('active').siblings().removeClass('active');
$('.term_content_tab .term_item:eq('+ index +')').addClass('active').siblings().removeClass('active');
that.host_term[data.id];
var item = that.host_term[data.id];
item.term.focus();
item.term.FitAddon.fit();
item.resize({cols:item.term.cols, rows:item.term.rows});
}
});
//通过本地存储获取显示设置
if(_tool_status==0){
$(".term-tool-button").empty();
$(".term-tool-button").append('<span class="glyphicon glyphicon-menu-right"></span>').addClass("tool-hide").removeClass("tool-show");
$(".term_box").css("margin-right","260px");
$(".term_tootls").css("display","block");
if(_tool_host_height !=0&&_tool_commonly_height !=0){
$(".tootls_host_list").css("height",_tool_host_height+"px"),
$(".tootls_commonly_list").css("height", _tool_commonly_height+"px");
}
}else{
$(".term-tool-button").empty();
$(".term-tool-button").append('<span class="glyphicon glyphicon-menu-left"></span>').addClass("tool-show").removeClass("tool-hide");
$(".term_box").css("margin-right","0px");
$(".term_tootls").css("display","none");
}
//终端工具栏显示
$('.term_content_tab').on('click','.tool-show',function(){
$(this).empty();
$(this).append('<span class="glyphicon glyphicon-menu-right"></span>').addClass("tool-hide").removeClass("tool-show");
$(".term_box").css("margin-right","260px");
$(".term_tootls").css("display","block");
localStorage.setItem("tool_status",0);
that.on_resize(that);
});
//终端工具栏隐藏
$('.term_content_tab').on('click','.tool-hide',function(){
$(this).empty();
$(this).append('<span class="glyphicon glyphicon-menu-left"></span>').addClass("tool-show").removeClass("tool-hide");
$(".term_box").css("margin-right","0px");
$(".term_tootls").css("display","none");
localStorage.setItem("tool_status",1);
that.on_resize(that);
});
$(".term-move-border").on('mousedown', function (e) {
var hostbox_height = parseInt($(".tootls_host_list").css("height")),
commonlybox_height = parseInt($(".tootls_commonly_list").css("height")),
max_height = hostbox_height + commonlybox_height+38,
move_y = e.clientY;
$(document).on('mousemove', function (ev) {
var offsetY = ev.clientY - move_y,
_host = hostbox_height+offsetY;
_commonly = commonlybox_height-offsetY;
if(_host <= 300){
_host = 300;_commonly = max_height-_host-38;
}else
if(_commonly <= 100){
_commonly = 100;_host = max_height-_commonly-38;
}
$(".tootls_host_list").css("height",_host+"px"),$(".tootls_commonly_list").css("height",_commonly+"px");
});
$(document).on('mouseup', function (ev) {
var _host_height = parseInt($(".tootls_host_list").css("height")),
_commonly_height = parseInt($(".tootls_commonly_list").css("height"));
localStorage.setItem("hostHeight",_host_height);
localStorage.setItem("commonlyHeight",_commonly_height);
$(this).unbind('mousemove mouseup');
});
e.stopPropagation();
});
$('.term_item_tab').on('click','.icon-trem-close',function(){
var id = $(this).parent().data('id');
that.remove_term_view(id);
})
// 服务器列表工具箱
$('.tootls_host_list').on('click','li .tootls span',function(ev){
var item = $(this).parent().parent(),host = item.data('host'),index = item.data('index');
if(!$(this).index()){
that.get_host_find(host,function(rdata){
if(rdata.status === false){
bt.msg(rdata);
return false;
}
that.editor_host_view({
form:rdata,
config: {btn: 'Save', title: 'Edit server information [ '+ host +' ]'}
});
});
}else{
bt.confirm({title:'Delete information',msg:'Delete service information [ '+ host +' ], continue?',icon:0},function(index){
that.remove_host(host,function(rdata){
layer.close(index);
that.reader_host_list(function(){
bt.msg(rdata);
});
});
});
}
ev.stopPropagation();
});
// 服务器列表工具箱
$('.tootls_commonly_list').on('click','li .tootls span',function(ev){
var item = $(this).parent().parent(),title = item.data('title'),index = item.data('index');
if(!$(this).index()){
that.get_command_find(title,function(rdata){
if(rdata.status === false){
bt.msg(rdata);
return false;
}
that.editor_command_view({
form:rdata,
config: {btn: 'Save', title: 'Edit command information【'+ title +'】'}
});
});
}else{
bt.confirm({title:'Delete command',msg:'Delete service command 【'+ title +'】, continue?',icon:0},function(index){
that.remove_command(title,function(rdata){
layer.close(index);
that.reader_command_list(function(){
bt.msg(rdata);
});
});
});
}
ev.stopPropagation();
});
// 右键菜单
$('.term_item_tab .list').on('mousedown','.item',function(ev){
if(ev.which == 3){
that.reader_right_menu({
el:$(this),
position:[ev.clientX,ev.clientY],
list:[
[{title:'Copy session',event:function(el,data){
that.open_term_view(that.host_term[data.id].ssh_info);
}}],
[{title:'Close session',event:function(el,data){
that.remove_term_view(data.id);
}},
{title:'Close to right',event:function(el,data){
bt.confirm({msg:'After closing the terminal session, the command in progress in the current command line session may be aborted. Continue?',title: "Close the terminal session?"},function(index){
that.remove_term_right_view(data.id);
layer.close(index);
});
}},
{title:'Close other',event:function(el,data){
bt.confirm({msg:'After closing the terminal session, the command in progress in the current command line session may be aborted. Continue?',title: "Close the terminal session?"},function(index){
that.remove_term_other_view(data.id);
layer.close(index);
});
}}]
]
},function(){
$(document).unbind('contextmenu');
});
ev.preventDefault();
$(document).contextmenu(function(e){
e.preventDefault();
});
}
});
// 添加服务器和常用秘钥
$('.term_tootls .tootls_tab a').click(function(){
var type = $(this).data('type');
if(type == 'host'){
that.editor_host_view();
}else{
that.editor_command_view();
}
});
// var clientX = null,clientY = null;
// $('.tootls_host_list').on('mousedown','li',function(e){
// clientX = e.clientX,clientY = e.clientY;
// })
// 模拟触发服务器列表点击事件
// $('.tootls_host_list').on('mouseup','li',function(e){
// if(e.button == 0){
// if(clientX == e.clientX && clientY == e.clientY){
// }
// }
// });
$('.tootls_host_list').on('click','li',function(e){
var index = $(this).index(),host = $(this).data('host');
$(this).find('i').addClass('active');
if($('.item[data-host="'+ host +'"]').length > 0){
layer.msg('For multi session window, right click the terminal title to copy the session!',{icon:0,time:3000})
}else{
that.open_term_view(that.host_list[index]);
}
});
// 服务器列表拖动
$('.tootls_host_list').dragsort({
dragSelector:'li i',
dragEnd:function(){
clearTimeout(that.sort_time);
that.sort_time = setTimeout(function(){
var sort_list = {};
$('.tootls_host_list li').each(function(index,el){
sort_list[$(this).data('host')] = index;
});
that.set_sort(sort_list,function(rdata){
if(!rdata.status){
bt.msg(rdata);
}
});
},500);
},
dragBetween:false,
});
this.reader_host_list();
this.reader_command_list();
},
// 判断全屏状态
isFullScreen:function() {
var is_full = document.isFullScreen || document.mozIsFullScreen || document.webkitIsFullScreen;
this.is_full = is_full
return is_full;
},
// 进入全屏
requestFullScreen:function(element){
if(element == undefined) element = document.documentElement;
// 判断各种浏览器,找到正确的方法
var requestMethod = element.requestFullScreen || //W3C
element.webkitRequestFullScreen || //FireFox
element.mozRequestFullScreen || //Chrome等
element.msRequestFullScreen; //IE11
if (requestMethod) {
requestMethod.call(element);
} else if (typeof window.ActiveXObject !== "undefined") { //for Internet Explorer
var wscript = new ActiveXObject("WScript.Shell");
if (wscript !== null) {
wscript.SendKeys("{F11}");
}
}
this.is_full = true;
},
// 退出全屏
exitFullscreen:function(element) {
if(element == undefined) element = document.documentElement;
// 判断各种浏览器,找到正确的方法
var exitMethod = document.exitFullscreen || //W3C
document.mozCancelFullScreen || //FireFox
document.webkitExitFullscreen || //Chrome等
document.webkitExitFullscreen; //IE11
if (exitMethod) {
exitMethod.call(document);
} else if (typeof window.ActiveXObject !== "undefined") { //for Internet Explorer
var wscript = new ActiveXObject("WScript.Shell");
if (wscript !== null) {
wscript.SendKeys("{F11}");
}
}
this.is_full = false;
},
on_resize:function(that){
var win = $(window)[0],win_width = win.innerHeight,win_height = win.innerHeight,host_commonly = win_height - 185;
if(that.isFullScreen()){
$('.main-content .safe').height(win_height);
$('#term_box_view,.term_tootls').height(win_height);
$('.tootls_host_list').height((win_height - 80) * .75);
$('.tootls_commonly_list').height((win_height - 80) * .25);
}else{
$('.main-content .safe').height(win_height - 105);
$('#term_box_view,.term_tootls').height(win_height - 105);
$('.tootls_host_list').height(host_commonly * .75);
$('.tootls_commonly_list').height(host_commonly * .25);
}
var id = $('.term_item_tab .active').data('id');
var item_term = that.host_term[id].term;
item_term.FitAddon.fit();
that.host_term[id].resize({cols:item_term.cols, rows:item_term.rows});
},
/**
* @name 本地服务器登录表单
* @author chudong<2020-08-10>
* @return void
*/
localhost_login_form:function(result){
var that = this,form = $(this.render_template({html:host_form_view.innerHTML,data:{form:$.extend(that.host_form,{host:'127.0.0.1'})}})),id = $('.localhost_item').data('id')
form.find('.ssh_ps_tips').remove();
form.prepend('<div class="localhost-form-title"><i class="localhost-form_tip"></i><span style="vertical-align: middle;">Login failed, please fill the local server information!</span></div>');
form.append('<button type="submit" class="btn btn-sm btn-success">Login</button>');
$('#'+id).append('<div class="localhost-form-shade"><div class="localhost-form-view bt-form-2x">'+ form[0].innerHTML +'</div></div>');
if(result){
if(result.indexOf('@127.0.0.1') != -1){
var user = result.split('@')[0].split(',')[1];
var port = result.split('1:')[1]
$("input[name='username']").val(user);
$("input[name='port']").val(port);
}
}
$('.auth_type_checkbox').click(function(){
var index = $(this).index();
$(this).addClass('btn-success').removeClass('btn-default').siblings().removeClass('btn-success').addClass('btn-default')
switch(index){
case 0:
$('.c_password_view').addClass('show').removeClass('hidden');
$('.c_pkey_view').addClass('hidden').removeClass('show').find('input').val('');
$('.key_pwd_line').addClass('hidden').removeClass('show');
break;
case 1:
$('.c_password_view').addClass('hidden').removeClass('show').find('input').val('');
$('.c_pkey_view').addClass('show').removeClass('hidden');
$('.key_pwd_line').addClass('show').removeClass('hidden');
break;
}
});
$('.localhost-form-view > button').click(function(){
var form = {};
$('.localhost-form-view input,.localhost-form-view textarea').each(function(index,el){
var name = $(this).attr('name'),value = $(this).val();
form[name] = value;
switch(name){
case 'port':
if(!bt.check_port(value)){
bt.msg({status:false,msg:'Server port format error!'});
return false;
}
break;
case 'username':
if(value == ''){
bt.msg({status:false,msg:'Server user name cannot be empty!'});
return false;
}
break;
case 'password':
if(value == '' && $('.c_password_view').hasClass('show')){
bt.msg({status:false,msg:'Server password cannot be empty!'});
return false;
}
break;
case 'pkey':
if(value == '' && $('.c_pkey_view').hasClass('show')){
bt.msg({status:false,msg:'The server key cannot be empty!'});
return false;
}
break;
}
});
delete form.sort
form.ps = 'Local server';
that.create_host(form,function(res){
bt.msg(res);
if(res.status){
bt.msg({status:true,msg:'Login successful!'});
$('.localhost_item .icon-trem-close').click();
that.open_term_view();
}
});
});
$('.localhost-form-view [name="password"]').keyup(function(e){
if(e.keyCode == 13){
$('.localhost-form-view > button').click();
}
}).focus();
},
reader_right_menu:function(config,callback){
var menu = $('<ul class="menu_right_list" id="term_title_menu"></ul>').css({'top':config.position[1],'left':config.position[0]}),html = '';
bt.each(config.list,function(index,item){
bt.each(item,function(indexs,items){
(function(items){
menu.append($('<li></li>').append($('<a href="javascript:;" title="'+ items.title +'">'+ items.title +'</a>').click(function(e){
if(items.event) items.event(config.el,$(config.el).data())
menu.remove();
if(callback) callback();
})));
}(items));
});
if(index != config.list.length - 1){
menu.append('<li class="split_line"></li>');
}
});
if(!$('#term_title_menu').length){
$('body').append(menu);
}else{
$('#term_title_menu').replaceWith(menu);
}
$(document).click(function(e){
menu.remove();
$(this).unbind('click');
if(callback) callback();
})
},
/**
* @name 主机信息添加或编辑
* @author chudong<2020-08-10>
* @param {Objeact} obj 需要编辑的form数据,可以为空为空则添加
* @return void
*/
editor_host_view:function(obj){
var that = this;
if (!obj) {
obj = {
form: this.host_form,
config: {
btn: 'Submit', title: 'Add host information'
}
}
}
this.render_template({
html: host_form_view.innerHTML,
data: obj
}, function (html) {
layer.open({
type: 1 //Page层类型
, area: '510px'
, closeBtn: 2
, title: obj.config.title
, btn: [obj.config.btn, 'Cancel']
, content: html
, success: function (layers, index) {
$('.auth_type_checkbox').click(function () {
var index = $(this).index();
$(this).addClass('btn-success').removeClass('btn-default').siblings().removeClass('btn-success').addClass('btn-default')
switch (index) {
case 0:
$('.c_password_view').addClass('show').removeClass('hidden');
$('.c_pkey_view').addClass('hidden').removeClass('show').find('input').val('');
$('.key_pwd_line').addClass('hidden').removeClass('show');
break;
case 1:
$('.c_password_view').addClass('hidden').removeClass('show').find('input').val('');
$('.c_pkey_view').addClass('show').removeClass('hidden');
$('.key_pwd_line').addClass('show').removeClass('hidden');
break;
}
});
$('[name="host"]').on('change',function(){
var host_val = $(this).val();
if(!host_val) return;
var s_host,s_port,s_username,s_password;
s_host = host_val;
if(host_val.indexOf('@') != -1){
var tmp = host_val.split('@')
s_host = tmp[1]
s_username = tmp[0]
if (s_username.indexOf(':') != -1){
var tmp = s_username.split(':')
s_username = tmp[0]
s_password = tmp[1]
}
}
if(s_host.indexOf(':')!=-1){
var tmp = s_host.split(':')
s_host = tmp[0]
s_port = tmp[1]
}
if(s_host) {
$(this).val(s_host);
$('[name="ps"]').val(s_host);
}
if(s_port) $('[name="port"]').val(s_port);
if(s_username) $('[name="username"]').val(s_username);
if(s_password) $('[name="password"]').val(s_password);
});
$('[name="host"]').on('input',function(){
$('[name="ps"]').val($(this).val());
});
$('[name="password"],[name="ps"]').keyup(function(e){
if(e.keyCode === 13){
$('#layui-layer'+ index +' .layui-layer-btn0').click();
}
});
},
yes:function(indexs,layero){
var form = {};
$('.bt-form input,.bt-form textarea').each(function(index,el){
var name = $(this).attr('name'),value = $(this).val();
form[name] = value;
switch(name){
// case 'host':
// if(!bt.check_ip(value)){
// bt.msg({status:false,msg:'服务器ip地址格式错误'});
// return false;
// }
// break;
case 'port':
if(!bt.check_port(value)){
bt.msg({status:false,msg:'Server port format error!'});
return false;
}
break;
case 'username':
if(value == ''){
bt.msg({status:false,msg:'Server user name cannot be empty!'});
return false;
}
break;
case 'password':
if(value == '' && $('.c_password_view').hasClass('show')){
bt.msg({status:false,msg:'Server password cannot be empty!'});
return false;
}
break;
case 'pkey':
if(value == '' && $('.c_pkey_view').hasClass('show')){
bt.msg({status:false,msg:'Server key cannot be empty!'});
return false;
}
break;
}
});
if(!obj.form.sort){
delete form.sort;
that.create_host(form,function(res){
if(res.status){
that.open_term_view(form);
layer.close(indexs)
that.reader_host_list(function(){
bt.msg(res);
})
}
});
}else{
form.new_host = form.host;
form.host = obj.form.host;
that.modify_host(form,function(res){
if(res.status){
layer.close(indexs)
that.reader_host_list(function(){
bt.msg(res);
})
}
})
}
}
});
});
},
/**
* @name 常用信息添加或编辑
* @author chudong<2020-08-10>
* @param {Objeact} obj 需要编辑的form数据,可以为空为空则添加
* @return void
*/
editor_command_view: function (obj) {
var that = this;
if (!obj) {
obj = {
form: this.command_form,
config: {
btn: 'Submit', title: 'Add command information'
}
};
}
this.render_template({
html: shell_form_view.innerHTML,
data: obj
}, function (html) {
layer.open({
type: 1 //Page层类型
, area: '510px'
, closeBtn: 2
, title: obj.config.title
, btn: [obj.config.btn, 'Cancel']
, content: html
, yes: function (indexs, layero) {
var shell = $('[name="shell"]').val(), title = $('[name="title"]').val();
if (title == '') {
bt.msg({status: false, msg: 'Command description cannot be empty!'});
return false;
}
if (shell == '') {
bt.msg({status: false, msg: 'Command cannot be empty!'});
return false;
}
if(!obj.form.title){
that.create_command({shell:shell,title:title},function(res){
if(res.status){
layer.close(indexs);
that.reader_command_list(function(){
bt.msg(res);
});
}
});
}else{
that.modify_command({new_title:title,title:obj.form.title,shell:shell},function(res){
if(res.status){
layer.close(indexs);
that.reader_command_list(function(){
bt.msg(res);
});
}
});
}
},
});
});
},
/**
* @name 设置终端标题状态
* @author chudong<2020-08-10>
* @param {String} id 终端ID
* @param {number} status 终端状态
* @return void
*/
set_term_icon:function(id,status){
var icon_list = ['icon-warning','icon-sucess','icon-info'];
$("[data-id='"+ id +"']").find('.icon').removeAttr('class').addClass(icon_list[status]+' icon');
},
/**
* @name 打开终端显示视图
* @author chudong<2020-08-10>
* @param {Objeact} info 终端数据 {
* ps:已添加的备注,
* host:已添加的服务器ip
* }
* @return void
*/
open_term_view:function(info){
if(typeof info === "undefined") info = {host:'127.0.0.1',ps:'Local server'}
var random = bt.get_random(9),tab_content = $('.term_content_tab'),item_list = $('.term_item_tab .list');
tab_content.find('.term_item').removeClass('active').siblings().removeClass('active');
tab_content.append('<div class="term_item active" id="'+ random +'" data-host="'+ info.host +'"></div>');
item_list.find('.item').removeClass('active');
item_list.append('<span class="active item '+ (info.host =='127.0.0.1'?'localhost_item':'') +'" data-host="'+ info.host +'" data-id="'+ random +'"><i class="icon icon-sucess"></i><div class="content"><span>'+ info.ps +'</span></div><span class="icon-trem-close"></span></span>');
this.host_term[random] = new Terms('#'+random,{ssh_info:{host:info.host,ps:info.ps,id:random}});
},
/**
* @name 关闭终端显示视图
* @author chudong<2020-08-10>
* @param {String} id 终端id
* @return void
*/
remove_term_view:function(id){
var item = $('[data-id="'+ id +'"]'),next = item.next(),prev = item.prev();
$('#'+id).remove();
item.remove();
try {
this.host_term[id].bws.close();
} catch (error) {
}
delete this.host_term[id];
if(item.hasClass('active')){
if(next.length > 0){
next.click();
}else{
prev.click();
}
}
},
/**
* @name 关闭选中右侧终端显示视图
* @author chudong<2020-08-10>
* @param {String} id 终端id
* @return void
*/
remove_term_right_view:function(id){
var arry = [],item = $('[data-id="'+ id +'"]'),nextAll = item.nextAll(),that = this;
if(!nextAll.length){
return false;
}
nextAll.each(function(index,el){
var data = $(this).data();
try {
that.host_term[data.id].bws.close();
} catch (error) {
}
delete that.host_term[data.id];
});
nextAll.remove();
item.addClass('active');
$('#'+id).addClass('active').nextAll().remove();
},
/**
* @name 关闭其他终端显示视图
* @author chudong<2020-08-10>
* @param {String} id 终端id
* @return void
*/
remove_term_other_view:function(id){
var arry = [],item = $('[data-id="'+ id +'"]'),siblings = item.siblings(),that = this;
if(!siblings.length){
return false;
}
siblings.each(function(index,el){
var data = $(this).data();
try {
that.host_term[data.id].bws.close();
} catch (error) {
}
delete that.host_term[data.id];
});
siblings.remove();
item.addClass('active');
$('#'+id).addClass('active').siblings().remove();
},
/**
* @name 渲染常用命令列表
* @author chudong<2020-08-10>
* @param {Objeact} callback 回调函数回调参数1:当前请求内容
* @return void
*/
reader_command_list:function(callback){
var that = this,html = '';
this.get_command_list(function(rdata){
bt.each(rdata,function(index,item){
html += '<li data-title="'+ item.title +'" data-index="'+ index +'" data-clipboard-text="'+ item.shell +'"><i></i><span>'+ item.title +'</span><span class="tootls">'+
'<span class="glyphicon glyphicon-edit" aria-hidden="true" title="Edit common command information"></span>'+
'<span class="glyphicon glyphicon-trash" aria-hidden="true" title="Delete common command information"></span>'+
'</span></li>';
});
$('.tootls_commonly_list').html(html);
var clipboard = new ClipboardJS('.tootls_commonly_list li');
clipboard.on('success', function(e) {
layer.msg('Copy succeeded!',{icon:1});
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
that.command_list = rdata;
if(callback) callback(rdata)
});
},
/**
* @name 渲染主机视图列表
* @author chudong<2020-08-10>
* @param {Objeact} callback 回调函数回调参数1:当前请求内容
* @return void
*/
reader_host_list:function(callback){
var that = this,html = '';
this.get_host_list(function(rdata){
bt.each(rdata,function(index,item){
html += '<li data-host="'+ item.host +'" data-index="'+ index +'"><i></i><span>'+ (item.ps == item.host?item.ps:(item.ps +'【'+ item.host +'】')) +'</span><span class="tootls">'+
'<span class="glyphicon glyphicon-edit" aria-hidden="true" title="Edit server information"></span>'+
'<span class="glyphicon glyphicon-trash" aria-hidden="true" title="Delete server information"></span>'+
'</span></li>';
});
$('.tootls_host_list').html(html);
that.host_list = rdata;
if(callback) callback()
});
},
/**
* @name 获取host列表
* @author chudong<2020-08-010>
* @param {Objeact} callback 回调函数回调参数1:当前请求内容
* @return void
*/
get_host_list:function(callback){
var loadT = bt.load('Getting server list, please wait...');
this.post('get_host_list',{},function(rdata){
loadT.close();
if(callback) callback(rdata);
});
},
/**
* @name 获取指定host信息
* @author hwliang<2020-08-07>
* @param host string host地址
* @return void
*/
get_host_find:function(host,callback){
var loadT = bt.load('Getting the specified server information, please wait...');
this.post('get_host_find',{host:host},function(rdata){
loadT.close();
if(callback) callback(rdata);
});
},
/**
* @name 创建新的host信息
* @author hwliang<2020-08-07>
* @param ssh_info array ssh信息对象 {
* host: 主机地址,
port: 端口
ps: 备注
username: 用户名
password: 密码
pkey: 密钥(如果不为空将使用密钥连接)
* }
* @return void
*/
create_host:function(ssh_info,callback){
var loadT = bt.load('Adding server information, please wait...');
this.post('create_host',ssh_info,function(rdata){
loadT.close();
if(!rdata.status){
bt.msg(rdata);
return false;
}
if(callback) callback(rdata);
});
},
/**
* @name 修改host信息
* @author hwliang<2020-08-07>
* @param ssh_info array ssh信息对象 {
* host: 主机地址,
port: 端口
ps: 备注
sort: 排序(可选默认0)
username: 用户名
password: 密码
pkey: 密钥(如果不为空将使用密钥连接)
* }
* @return void
*/
modify_host:function(ssh_info,callback){
var loadT = bt.load('Modifying the specified server information, please wait...');
this.post('modify_host',ssh_info,function(rdata){
loadT.close();
if(callback) callback(rdata);
});
},
/**
* @name 删除host信息
* @author hwliang<2020-08-07>
* @param host string host地址
* @return void
*/
remove_host:function(host,callback){
var loadT = bt.load('Deleting specified server information, please wait...');
this.post('remove_host',{host:host},function(rdata){
loadT.close();
if(callback) callback(rdata);
});
},
/**
* @name 设置host排序(使用降序)
* @author hwliang<2020-08-07>
* @param sort_list array 排序对象{
* "127.0.0.1":3,
* "192.168.1.254":2
* }
* @return void
*/
set_sort:function(sort_list,callabck){
this.post('set_sort',{sort_list:JSON.stringify(sort_list)},function(rdata){
if(callabck) callabck(rdata);
});
},
/**
* @name 获取常用命令列表
* @author hwliang<2020-08-08>
* @return void
*/
get_command_list: function(callback){
var loadT = bt.load('Getting list of frequently used commands, please wait...');
this.post('get_command_list',{},function(rdata){
loadT.close();
if(callback) callback(rdata);
});
},
/**
* @name 创建常用命令
* @author hwliang<2020-08-08>
* @param {title} string 命令标题
* @parma {shell} string 命令文本
* @return void
*/
create_command: function(obj,callback){
var loadT = bt.load('Creating common commands, please wait...');
this.post('create_command',obj,function(rdata){
loadT.close();
if(callback) callback(rdata);
});
},
/**
* @name 获取指定常用命令
* @author hwliang<2020-08-08>
* @param {title} string 命令标题
* @return void
*/
get_command_find: function(title,callback){
var loadT = bt.load('Getting specified common command data, please wait...');
this.post('get_command_find',{title:title},function(rdata){
loadT.close();
if(callback) callback(rdata);
});
},
/**
* @name 修改常用命令
* @author hwliang<2020-08-08>
* @param {title} string 命令标题
* @param {new_title} string 新的命令标题
* @parma {shell} string 命令文本
* @return void
*/
modify_command: function(obj,callback){
var loadT = bt.load('Modifying specified common commands, please wait...');
this.post('modify_command',obj,function(rdata){
loadT.close();
if(callback) callback(rdata);
});
},
/**
* @name 删除指定常用命令
* @author hwliang<2020-08-08>
* @param {title} string 命令标题
* @return void
*/
remove_command: function(title,callback){
var loadT = bt.load('Deleting specified common commands, please wait...');
this.post('remove_command',{title:title},function(rdata){
loadT.close();
// console.log(rdata)
if(callback) callback(rdata);
});
},
/**
* @name 请求到后端
* @author hwliang<2020-08-07>
* @param fun_name string 要访问的方法名称
* @param pdata array POST数据
* @param callback function 回调函数
* @return void
*/
post:function(fun_name,pdata,callback){
bt.send(fun_name,'xterm/'+fun_name,pdata,callback);
},
/**
* @author chudong<2020-08-08>
* @param {Object} obj 需要渲染的配置对象
* @param {*} callback 渲染完成的回调方法
*/
render_template:function(obj, callback) {
if (!obj.html) return '缺少模板HTML';
var re = /<%([^%>]+)?%>/g, reExp = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g, code = 'var r=[];\n',
cursor = 0;
var add = function (line, js) {
js ? (code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n') :
(code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : '');
return add;
}
while (match = re.exec(obj.html)) {
add(obj.html.slice(cursor, match.index))(match[1], true);
cursor = match.index + match[0].length;
}
add(obj.html.substr(cursor, obj.html.length - cursor));
code += 'return r.join("");';
if (callback) {
callback(new Function(code.replace(/[\r\t\n]/g, '')).apply(obj.data));
} else {
return new Function(code.replace(/[\r\t\n]/g, '')).apply(obj.data);
}
}
}
host_trem.init();