mirror of https://github.com/tp4a/teleport
(未完成)加入第三方服务集成所需密钥管理界面及数据库表
parent
916b82d649
commit
8b106a8be6
|
@ -155,7 +155,7 @@ class BuilderWin(BuilderBase):
|
||||||
installer = os.path.join(PATH_DOWNLOAD, file_name)
|
installer = os.path.join(PATH_DOWNLOAD, file_name)
|
||||||
|
|
||||||
if not os.path.exists(installer):
|
if not os.path.exists(installer):
|
||||||
if not utils.download_file('openssl installer', 'http://slproweb.com/download/{}'.format(filename), PATH_DOWNLOAD, file_name):
|
if not utils.download_file('openssl installer', 'http://slproweb.com/download/{}'.format(file_name), PATH_DOWNLOAD, file_name):
|
||||||
cc.e('can not download pre-built installer of OpenSSL.')
|
cc.e('can not download pre-built installer of OpenSSL.')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,13 @@
|
||||||
"cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}",
|
"cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}",
|
||||||
"desc": []
|
"desc": []
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "mobaxterm",
|
||||||
|
"display": "MobaXterm",
|
||||||
|
"app": "",
|
||||||
|
"cmdline": "-newtab \"sshpass -p**** ssh {user_name}@{host_ip} -p {host_port}\"",
|
||||||
|
"desc": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "other",
|
"name": "other",
|
||||||
"display": "自定义",
|
"display": "自定义",
|
||||||
|
|
|
@ -21,11 +21,15 @@ $app.on_init = function (cb_stack) {
|
||||||
$app.storage = $app.create_config_storage();
|
$app.storage = $app.create_config_storage();
|
||||||
cb_stack.add($app.storage.init);
|
cb_stack.add($app.storage.init);
|
||||||
|
|
||||||
|
$app.integration = $app.create_config_integration();
|
||||||
|
cb_stack.add($app.integration.init);
|
||||||
|
|
||||||
|
cb_stack.add($app.load_role_list);
|
||||||
cb_stack.exec();
|
cb_stack.exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.create_info_table = function () {
|
$app.create_info_table = function () {
|
||||||
var _info = {};
|
let _info = {};
|
||||||
|
|
||||||
_info.dom = {
|
_info.dom = {
|
||||||
web_info: $('#web-info-kv'),
|
web_info: $('#web-info-kv'),
|
||||||
|
@ -33,7 +37,7 @@ $app.create_info_table = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
_info.init = function (cb_stack) {
|
_info.init = function (cb_stack) {
|
||||||
var h = [];
|
let h = [];
|
||||||
|
|
||||||
h.push(_info._make_info('WEB服务版本', $app.options.web_cfg.version));
|
h.push(_info._make_info('WEB服务版本', $app.options.web_cfg.version));
|
||||||
|
|
||||||
|
@ -79,7 +83,7 @@ $app.create_info_table = function () {
|
||||||
_info._make_protocol_info = function (name, p) {
|
_info._make_protocol_info = function (name, p) {
|
||||||
if (_.isUndefined(p))
|
if (_.isUndefined(p))
|
||||||
return _info._make_info(name, '未能检测到');
|
return _info._make_info(name, '未能检测到');
|
||||||
var val = p.port;
|
let val = p.port;
|
||||||
if (!p.enable) {
|
if (!p.enable) {
|
||||||
val = '<span class="disabled">' + val + '(未启用)</span>';
|
val = '<span class="disabled">' + val + '(未启用)</span>';
|
||||||
}
|
}
|
||||||
|
@ -91,7 +95,7 @@ $app.create_info_table = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.create_dlg_result = function () {
|
$app.create_dlg_result = function () {
|
||||||
var _dlg = {};
|
let _dlg = {};
|
||||||
|
|
||||||
_dlg.dom = {
|
_dlg.dom = {
|
||||||
dlg: $('#dlg-result'),
|
dlg: $('#dlg-result'),
|
||||||
|
@ -109,7 +113,7 @@ $app.create_dlg_result = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.create_config_smtp = function () {
|
$app.create_config_smtp = function () {
|
||||||
var _smtp = {};
|
let _smtp = {};
|
||||||
|
|
||||||
_smtp.dom = {
|
_smtp.dom = {
|
||||||
server: $('#smtp-server-info'),
|
server: $('#smtp-server-info'),
|
||||||
|
@ -154,7 +158,7 @@ $app.create_config_smtp = function () {
|
||||||
|
|
||||||
_smtp.update_dom = function (smtp) {
|
_smtp.update_dom = function (smtp) {
|
||||||
if (0 === smtp.server.length) {
|
if (0 === smtp.server.length) {
|
||||||
var not_set = '<span class="error">未设置</span>';
|
let not_set = '<span class="error">未设置</span>';
|
||||||
_smtp.dom.server.html(not_set);
|
_smtp.dom.server.html(not_set);
|
||||||
_smtp.dom.port.html(not_set);
|
_smtp.dom.port.html(not_set);
|
||||||
_smtp.dom.ssl.html(not_set);
|
_smtp.dom.ssl.html(not_set);
|
||||||
|
@ -168,7 +172,7 @@ $app.create_config_smtp = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
_smtp.on_edit = function () {
|
_smtp.on_edit = function () {
|
||||||
var smtp = $app.options.sys_cfg.smtp;
|
let smtp = $app.options.sys_cfg.smtp;
|
||||||
|
|
||||||
_smtp.dom.input_server.val(smtp.server);
|
_smtp.dom.input_server.val(smtp.server);
|
||||||
|
|
||||||
|
@ -211,12 +215,12 @@ $app.create_config_smtp = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
_smtp.on_btn_send = function () {
|
_smtp.on_btn_send = function () {
|
||||||
var _server = _smtp.dom.input_server.val();
|
let _server = _smtp.dom.input_server.val();
|
||||||
var _port = _smtp.dom.input_port.val();
|
let _port = _smtp.dom.input_port.val();
|
||||||
var _sender = _smtp.dom.input_sender.val();
|
let _sender = _smtp.dom.input_sender.val();
|
||||||
var _password = _smtp.dom.input_password.val();
|
let _password = _smtp.dom.input_password.val();
|
||||||
var _recipient = _smtp.dom.input_recipient.val();
|
let _recipient = _smtp.dom.input_recipient.val();
|
||||||
var _ssl = _smtp.dom.input_ssl.hasClass('tp-selected');
|
let _ssl = _smtp.dom.input_ssl.hasClass('tp-selected');
|
||||||
|
|
||||||
if (!_smtp._check_input(_server, _port, _sender, _password))
|
if (!_smtp._check_input(_server, _port, _sender, _password))
|
||||||
return;
|
return;
|
||||||
|
@ -254,11 +258,11 @@ $app.create_config_smtp = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
_smtp.on_btn_save = function () {
|
_smtp.on_btn_save = function () {
|
||||||
var _server = _smtp.dom.input_server.val();
|
let _server = _smtp.dom.input_server.val();
|
||||||
var _port = _smtp.dom.input_port.val();
|
let _port = _smtp.dom.input_port.val();
|
||||||
var _sender = _smtp.dom.input_sender.val();
|
let _sender = _smtp.dom.input_sender.val();
|
||||||
var _password = _smtp.dom.input_password.val();
|
let _password = _smtp.dom.input_password.val();
|
||||||
var _ssl = _smtp.dom.input_ssl.hasClass('tp-selected');
|
let _ssl = _smtp.dom.input_ssl.hasClass('tp-selected');
|
||||||
|
|
||||||
if (!_smtp._check_input(_server, _port, _sender, _password))
|
if (!_smtp._check_input(_server, _port, _sender, _password))
|
||||||
return;
|
return;
|
||||||
|
@ -304,7 +308,7 @@ $app.create_config_smtp = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.create_config_sec = function () {
|
$app.create_config_sec = function () {
|
||||||
var _sec = {};
|
let _sec = {};
|
||||||
|
|
||||||
_sec.dom = {
|
_sec.dom = {
|
||||||
btn_save: $('#btn-save-secure-config'),
|
btn_save: $('#btn-save-secure-config'),
|
||||||
|
@ -383,15 +387,15 @@ $app.create_config_sec = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
_sec.on_btn_save = function () {
|
_sec.on_btn_save = function () {
|
||||||
var _password_allow_reset = _sec.dom.btn_password_allow_reset.hasClass('tp-selected');
|
let _password_allow_reset = _sec.dom.btn_password_allow_reset.hasClass('tp-selected');
|
||||||
var _password_force_strong = _sec.dom.btn_password_force_strong.hasClass('tp-selected');
|
let _password_force_strong = _sec.dom.btn_password_force_strong.hasClass('tp-selected');
|
||||||
var _password_timeout = parseInt(_sec.dom.input_password_timeout.val());
|
let _password_timeout = parseInt(_sec.dom.input_password_timeout.val());
|
||||||
|
|
||||||
var _login_session_timeout = parseInt(_sec.dom.input_session_timeout.val());
|
let _login_session_timeout = parseInt(_sec.dom.input_session_timeout.val());
|
||||||
var _login_retry = parseInt(_sec.dom.input_login_retry.val());
|
let _login_retry = parseInt(_sec.dom.input_login_retry.val());
|
||||||
var _login_lock_timeout = parseInt(_sec.dom.input_lock_timeout.val());
|
let _login_lock_timeout = parseInt(_sec.dom.input_lock_timeout.val());
|
||||||
|
|
||||||
var _login_auth = 0;
|
let _login_auth = 0;
|
||||||
// if (_sec.dom.btn_auth_username_password.hasClass('tp-selected'))
|
// if (_sec.dom.btn_auth_username_password.hasClass('tp-selected'))
|
||||||
// _login_auth |= TP_LOGIN_AUTH_USERNAME_PASSWORD;
|
// _login_auth |= TP_LOGIN_AUTH_USERNAME_PASSWORD;
|
||||||
if (_sec.dom.btn_auth_username_password_captcha.hasClass('tp-selected'))
|
if (_sec.dom.btn_auth_username_password_captcha.hasClass('tp-selected'))
|
||||||
|
@ -500,7 +504,7 @@ $app.create_config_sec = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.create_config_sess = function () {
|
$app.create_config_sess = function () {
|
||||||
var _sess = {};
|
let _sess = {};
|
||||||
|
|
||||||
_sess.dom = {
|
_sess.dom = {
|
||||||
btn_save: $('#btn-save-session-config'),
|
btn_save: $('#btn-save-session-config'),
|
||||||
|
@ -556,23 +560,23 @@ $app.create_config_sess = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
_sess.on_btn_save = function () {
|
_sess.on_btn_save = function () {
|
||||||
var flag_record = 0;
|
let flag_record = 0;
|
||||||
flag_record |= TP_FLAG_RECORD_REPLAY; // now we always need record replay.
|
flag_record |= TP_FLAG_RECORD_REPLAY; // now we always need record replay.
|
||||||
flag_record |= TP_FLAG_RECORD_REAL_TIME; // not implement, set this flag for default.
|
flag_record |= TP_FLAG_RECORD_REAL_TIME; // not implement, set this flag for default.
|
||||||
|
|
||||||
var flag_rdp = 0;
|
let flag_rdp = 0;
|
||||||
flag_rdp |= TP_FLAG_RDP_DESKTOP; // before support remote-app, remote-desktop is the only way to access remote host.
|
flag_rdp |= TP_FLAG_RDP_DESKTOP; // before support remote-app, remote-desktop is the only way to access remote host.
|
||||||
if(_sess.dom.btn_sess_rdp_allow_clipboard.hasClass('tp-selected'))
|
if (_sess.dom.btn_sess_rdp_allow_clipboard.hasClass('tp-selected'))
|
||||||
flag_rdp |= TP_FLAG_RDP_CLIPBOARD;
|
flag_rdp |= TP_FLAG_RDP_CLIPBOARD;
|
||||||
if(_sess.dom.btn_sess_rdp_allow_disk.hasClass('tp-selected'))
|
if (_sess.dom.btn_sess_rdp_allow_disk.hasClass('tp-selected'))
|
||||||
flag_rdp |= TP_FLAG_RDP_DISK;
|
flag_rdp |= TP_FLAG_RDP_DISK;
|
||||||
if(_sess.dom.btn_sess_rdp_allow_console.hasClass('tp-selected'))
|
if (_sess.dom.btn_sess_rdp_allow_console.hasClass('tp-selected'))
|
||||||
flag_rdp |= TP_FLAG_RDP_CONSOLE;
|
flag_rdp |= TP_FLAG_RDP_CONSOLE;
|
||||||
|
|
||||||
var flag_ssh = 0;
|
let flag_ssh = 0;
|
||||||
if(_sess.dom.btn_sess_ssh_allow_shell.hasClass('tp-selected'))
|
if (_sess.dom.btn_sess_ssh_allow_shell.hasClass('tp-selected'))
|
||||||
flag_ssh |= TP_FLAG_SSH_SHELL;
|
flag_ssh |= TP_FLAG_SSH_SHELL;
|
||||||
if(_sess.dom.btn_sess_ssh_allow_sftp.hasClass('tp-selected'))
|
if (_sess.dom.btn_sess_ssh_allow_sftp.hasClass('tp-selected'))
|
||||||
flag_ssh |= TP_FLAG_SSH_SFTP;
|
flag_ssh |= TP_FLAG_SSH_SFTP;
|
||||||
|
|
||||||
if (flag_ssh === 0) {
|
if (flag_ssh === 0) {
|
||||||
|
@ -580,7 +584,7 @@ $app.create_config_sess = function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var _noop_timeout = parseInt(_sess.dom.input_noop_timeout.val());
|
let _noop_timeout = parseInt(_sess.dom.input_noop_timeout.val());
|
||||||
|
|
||||||
|
|
||||||
if (_.isNaN(_noop_timeout) || _noop_timeout < 0 || _noop_timeout > 60) {
|
if (_.isNaN(_noop_timeout) || _noop_timeout < 0 || _noop_timeout > 60) {
|
||||||
|
@ -632,7 +636,7 @@ $app.create_config_sess = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.create_config_storage = function () {
|
$app.create_config_storage = function () {
|
||||||
var _sto = {};
|
let _sto = {};
|
||||||
|
|
||||||
_sto.dom = {
|
_sto.dom = {
|
||||||
storage_size: $('#storage-size'),
|
storage_size: $('#storage-size'),
|
||||||
|
@ -648,7 +652,7 @@ $app.create_config_storage = function () {
|
||||||
|
|
||||||
_sto.init = function (cb_stack) {
|
_sto.init = function (cb_stack) {
|
||||||
// 当前会话录像存储空间:总 123.35GB,可用空间 85.17GB。
|
// 当前会话录像存储空间:总 123.35GB,可用空间 85.17GB。
|
||||||
var _info = [];
|
let _info = [];
|
||||||
if (!$app.options.core_cfg.detected) {
|
if (!$app.options.core_cfg.detected) {
|
||||||
_sto.dom.storage_size.removeClass().addClass('alert alert-danger');
|
_sto.dom.storage_size.removeClass().addClass('alert alert-danger');
|
||||||
_info.push('未能连接到核心服务,无法获取存储空间信息!');
|
_info.push('未能连接到核心服务,无法获取存储空间信息!');
|
||||||
|
@ -668,7 +672,7 @@ $app.create_config_storage = function () {
|
||||||
_sto.on_btn_cleanup();
|
_sto.on_btn_cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
_sto.dom.btn_export_db.click(function() {
|
_sto.dom.btn_export_db.click(function () {
|
||||||
_sto.on_export_db();
|
_sto.on_export_db();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -683,11 +687,11 @@ $app.create_config_storage = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
_sto.on_btn_save = function () {
|
_sto.on_btn_save = function () {
|
||||||
var _keep_log = parseInt(_sto.dom.input_keep_log.val());
|
let _keep_log = parseInt(_sto.dom.input_keep_log.val());
|
||||||
var _keep_record = parseInt(_sto.dom.input_keep_record.val());
|
let _keep_record = parseInt(_sto.dom.input_keep_record.val());
|
||||||
|
|
||||||
var _cleanup_hour = parseInt(_sto.dom.select_cleanup_hour.val());
|
let _cleanup_hour = parseInt(_sto.dom.select_cleanup_hour.val());
|
||||||
var _cleanup_minute = parseInt(_sto.dom.select_cleanup_minute.val());
|
let _cleanup_minute = parseInt(_sto.dom.select_cleanup_minute.val());
|
||||||
|
|
||||||
if (!(_keep_log === 0 || (_keep_log >= 30 && _keep_log <= 365))) {
|
if (!(_keep_log === 0 || (_keep_log >= 30 && _keep_log <= 365))) {
|
||||||
$tp.notify_error('日志保留时间超出范围!');
|
$tp.notify_error('日志保留时间超出范围!');
|
||||||
|
@ -734,8 +738,8 @@ $app.create_config_storage = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
_sto.on_btn_cleanup = function () {
|
_sto.on_btn_cleanup = function () {
|
||||||
var _keep_log = parseInt(_sto.dom.input_keep_log.val());
|
let _keep_log = parseInt(_sto.dom.input_keep_log.val());
|
||||||
var _keep_record = parseInt(_sto.dom.input_keep_record.val());
|
let _keep_record = parseInt(_sto.dom.input_keep_record.val());
|
||||||
|
|
||||||
if ($app.options.sys_cfg.storage.keep_log !== _keep_log || $app.options.sys_cfg.storage.keep_record !== _keep_record) {
|
if ($app.options.sys_cfg.storage.keep_log !== _keep_log || $app.options.sys_cfg.storage.keep_record !== _keep_record) {
|
||||||
$tp.notify_error('您已经修改了设置,请先保存设置,再进行清理!');
|
$tp.notify_error('您已经修改了设置,请先保存设置,再进行清理!');
|
||||||
|
@ -751,11 +755,10 @@ $app.create_config_storage = function () {
|
||||||
function (ret) {
|
function (ret) {
|
||||||
_sto.dom.btn_cleanup.removeAttr('disabled');
|
_sto.dom.btn_cleanup.removeAttr('disabled');
|
||||||
if (ret.code === TPE_OK) {
|
if (ret.code === TPE_OK) {
|
||||||
console.log(ret);
|
|
||||||
$tp.notify_success('清理存储空间成功!');
|
$tp.notify_success('清理存储空间成功!');
|
||||||
|
|
||||||
var msg = [];
|
let msg = [];
|
||||||
for (var i = 0; i < ret.data.length; ++i) {
|
for (let i = 0; i < ret.data.length; ++i) {
|
||||||
msg.push('<p>' + ret.data[i] + '</p>');
|
msg.push('<p>' + ret.data[i] + '</p>');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,9 +775,402 @@ $app.create_config_storage = function () {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
_sto.on_export_db = function() {
|
_sto.on_export_db = function () {
|
||||||
window.location.href = '/system/export-db';
|
window.location.href = '/system/export-db';
|
||||||
};
|
};
|
||||||
|
|
||||||
return _sto;
|
return _sto;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.create_config_integration = function () {
|
||||||
|
let _obj = {};
|
||||||
|
|
||||||
|
_obj.dom = {
|
||||||
|
btn_refresh_integration: $('#btn-refresh-integration'),
|
||||||
|
btn_add_integration: $('#btn-add-integration'),
|
||||||
|
select_all_integration: $('#table-integration-select-all'),
|
||||||
|
btn_remove_integration: $('#btn-remove-integration'),
|
||||||
|
};
|
||||||
|
|
||||||
|
_obj.init = function (cb_stack) {
|
||||||
|
_obj.dlg_edit_integration = _obj.create_dlg_edit_integration();
|
||||||
|
cb_stack.add(_obj.dlg_edit_integration.init);
|
||||||
|
|
||||||
|
_obj.dom.btn_add_integration.click(function () {
|
||||||
|
_obj.dlg_edit_integration.show_create();
|
||||||
|
});
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
// 第三方集成配置列表表格
|
||||||
|
//-------------------------------
|
||||||
|
let table_integration_options = {
|
||||||
|
dom_id: 'table-integration',
|
||||||
|
data_source: {
|
||||||
|
type: 'ajax-post',
|
||||||
|
url: '/system/get-integration'
|
||||||
|
},
|
||||||
|
message_no_data: '尚未配置外部服务集成密钥...',
|
||||||
|
column_default: {sort: false, align: 'left'},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
// title: '<a href="javascript:" data-reset-filter><i class="fa fa-undo fa-fw"></i></a>',
|
||||||
|
title: '',
|
||||||
|
key: 'chkbox',
|
||||||
|
width: 36,
|
||||||
|
align: 'center',
|
||||||
|
render: 'make_check_box',
|
||||||
|
fields: {id: 'id'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '服务名称',
|
||||||
|
key: 'name',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Access Key',
|
||||||
|
key: 'acc_key',
|
||||||
|
width: 160,
|
||||||
|
render: 'acc_key',
|
||||||
|
// fields: {acc_key: 'acc_key'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '备注',
|
||||||
|
key: 'comment',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '权限角色',
|
||||||
|
key: 'role_name',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
key: 'action',
|
||||||
|
align: 'center',
|
||||||
|
width: 200,
|
||||||
|
render: 'make_action_btn',
|
||||||
|
fields: {id: 'id'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// 重载回调函数
|
||||||
|
on_render_created: _obj.on_table_integration_render_created,
|
||||||
|
on_cell_created: _obj.on_table_integration_cell_created
|
||||||
|
};
|
||||||
|
_obj.table_integration = $tp.create_table(table_integration_options);
|
||||||
|
cb_stack
|
||||||
|
.add(_obj.table_integration.load_data)
|
||||||
|
.add(_obj.table_integration.init);
|
||||||
|
|
||||||
|
_obj.dom.btn_refresh_integration.click(function () {
|
||||||
|
_obj.table_integration.load_data();
|
||||||
|
});
|
||||||
|
_obj.dom.select_all_integration.click(function () {
|
||||||
|
let _objects = $('#' + _obj.table_integration.dom_id + ' tbody').find('[data-check-box]');
|
||||||
|
if ($(this).is(':checked')) {
|
||||||
|
$.each(_objects, function (i, _obj) {
|
||||||
|
$(_obj).prop('checked', true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$.each(_objects, function (i, _obj) {
|
||||||
|
$(_obj).prop('checked', false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_obj.dom.btn_remove_integration.click(function () {
|
||||||
|
_obj.on_btn_remove_integration_click();
|
||||||
|
});
|
||||||
|
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
_obj.on_table_integration_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
||||||
|
if (col_key === 'chkbox') {
|
||||||
|
cell_obj.find('[data-check-box]').click(function () {
|
||||||
|
_obj.check_integration_all_selected();
|
||||||
|
});
|
||||||
|
} else if (col_key === 'action') {
|
||||||
|
let _row_id = row_id;
|
||||||
|
cell_obj.find('[data-btn-edit]').click(function () {
|
||||||
|
_obj.dlg_edit_integration.show_edit(_row_id);
|
||||||
|
});
|
||||||
|
cell_obj.find('[data-btn-remove]').click(function () {
|
||||||
|
_obj.on_btn_remove_integration_click(_row_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_obj.on_table_integration_render_created = function (render) {
|
||||||
|
render.make_check_box = function (row_id, fields) {
|
||||||
|
return '<span><input type="checkbox" data-check-box="' + fields.id + '" data-row-id="' + row_id + '"></span>';
|
||||||
|
};
|
||||||
|
|
||||||
|
render.acc_key = function (row_id, fields) {
|
||||||
|
return '<span class="mono">' + fields.acc_key + '</span>';
|
||||||
|
};
|
||||||
|
|
||||||
|
render.make_action_btn = function (row_id, fields) {
|
||||||
|
let ret = [];
|
||||||
|
ret.push('<div class="btn-group btn-group-sm" role="group">');
|
||||||
|
ret.push('<btn class="btn btn-primary" data-btn-edit="edit"><i class="fa fa-edit"></i> 编辑</btn>');
|
||||||
|
ret.push('<btn class="btn btn-danger" data-btn-remove="' + fields.id + '"><i class="fas fa-trash-alt"></i> 删除</btn>');
|
||||||
|
ret.push('</div>');
|
||||||
|
return ret.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
_obj.check_integration_all_selected = function () {
|
||||||
|
let _all_checked = true;
|
||||||
|
let _objs = $('#' + _obj.table_integration.dom_id + ' tbody').find('[data-check-box]');
|
||||||
|
$.each(_objs, function (i, _obj) {
|
||||||
|
if (!$(_obj).is(':checked')) {
|
||||||
|
_all_checked = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_all_checked) {
|
||||||
|
_obj.dom.select_all_integration.prop('checked', true);
|
||||||
|
} else {
|
||||||
|
_obj.dom.select_all_integration.prop('checked', false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_obj.get_selected_integration = function (tbl) {
|
||||||
|
let items = [];
|
||||||
|
let _objs = $('#' + _obj.table_integration.dom_id + ' tbody tr td input[data-check-box]');
|
||||||
|
$.each(_objs, function (i, _obj) {
|
||||||
|
if ($(_obj).is(':checked')) {
|
||||||
|
let _row_data = tbl.get_row(_obj);
|
||||||
|
items.push(_row_data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return items;
|
||||||
|
};
|
||||||
|
|
||||||
|
_obj.on_btn_remove_integration_click = function (_row_id) {
|
||||||
|
let remove_list = [];
|
||||||
|
|
||||||
|
if (_.isUndefined(_row_id)) {
|
||||||
|
let items = _obj.get_selected_integration(_obj.table_integration);
|
||||||
|
if (items.length === 0) {
|
||||||
|
$tp.notify_error('请选择要删除的外部密钥!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.each(items, function (i, g) {
|
||||||
|
remove_list.push(g.id);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let _row_data = _obj.table_integration.get_row(_row_id);
|
||||||
|
remove_list.push(_row_data.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let _fn_sure = function (cb_stack, cb_args) {
|
||||||
|
$tp.ajax_post_json('/system/remove-integration', {items: remove_list},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
_obj.table_integration.load_data();
|
||||||
|
$tp.notify_success('删除外部密钥操作成功!');
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('删除外部密钥操作失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
cb_stack.exec();
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$tp.notify_error('网络故障,删除外部密钥操作失败!');
|
||||||
|
cb_stack.exec();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let cb_stack = CALLBACK_STACK.create();
|
||||||
|
let _msg_remove = '您确定要移除此外部密钥吗?';
|
||||||
|
if (remove_list.length > 1)
|
||||||
|
_msg_remove = '您确定要移除选定的 <strong>' + remove_list.length + '个</strong> 外部密钥吗?';
|
||||||
|
$tp.dlg_confirm(cb_stack, {
|
||||||
|
msg: '<div class="alert alert-danger"><p><strong>注意:删除操作不可恢复!!</strong></p><p>删除外部密钥会导致使用这些外部密钥的第三方应用再也无法调用Teleport的API接口!</p></div><p>' + _msg_remove + '</p>',
|
||||||
|
fn_yes: _fn_sure
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
_obj.create_dlg_edit_integration = function () {
|
||||||
|
let dlg = {};
|
||||||
|
dlg.dom_id = 'dlg-edit-integration';
|
||||||
|
dlg.field_id = -1; // 密钥id(仅编辑模式)
|
||||||
|
dlg.field_acc_key = ''; // access-key(仅编辑模式)
|
||||||
|
dlg.field_role = -1;
|
||||||
|
dlg.field_name = '';
|
||||||
|
dlg.field_comment = '';
|
||||||
|
|
||||||
|
dlg.dom = {
|
||||||
|
dialog: $('#' + dlg.dom_id)
|
||||||
|
, dlg_title: $('#' + dlg.dom_id + ' [data-field="dlg-title"]')
|
||||||
|
, select_role: $('#edit-integration-role')
|
||||||
|
, edit_name: $('#edit-integration-name')
|
||||||
|
, edit_comment: $('#edit-integration-comment')
|
||||||
|
, btn_save: $('#btn-edit-integration-save')
|
||||||
|
, area_regenerate: $('#area-integration-regenerate')
|
||||||
|
, chk_regenerate: $('#chk-integration-regenerate')
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.init = function (cb_stack) {
|
||||||
|
// 创建角色选择框
|
||||||
|
let _ret = [
|
||||||
|
'<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown">',
|
||||||
|
'<span data-selected-role>选择角色</span> <i class="fa fa-caret-right"></i></button>',
|
||||||
|
'<ul class="dropdown-menu dropdown-menu-sm">'
|
||||||
|
];
|
||||||
|
$.each($app.role_list, function (i, role) {
|
||||||
|
_ret.push('<li><a href="javascript:;" data-tp-selector="' + role.id + '"><i class="fa fa-user-circle fa-fw"></i> ' + role.name + '</a></li>');
|
||||||
|
});
|
||||||
|
_ret.push('</ul>');
|
||||||
|
dlg.dom.select_role.after($(_ret.join('')));
|
||||||
|
|
||||||
|
// 动态创建的dom对象,需要创建完成后再绑定。
|
||||||
|
dlg.dom.selected_role = $('#' + dlg.dom_id + ' span[data-selected-role]');
|
||||||
|
|
||||||
|
// 绑定角色选择框事件
|
||||||
|
$('#' + dlg.dom_id + ' li a[data-tp-selector]').click(function () {
|
||||||
|
let select = parseInt($(this).attr('data-tp-selector'));
|
||||||
|
if (dlg.field_role === select)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let name = $app.role_id2name(select);
|
||||||
|
if (_.isUndefined(name)) {
|
||||||
|
name = '选择角色';
|
||||||
|
dlg.field_role = -1;
|
||||||
|
} else {
|
||||||
|
dlg.field_role = select;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlg.dom.selected_role.text(name);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
dlg.dom.btn_save.click(dlg.on_save);
|
||||||
|
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.init_fields = function (data) {
|
||||||
|
let role_name = '选择角色';
|
||||||
|
dlg.field_role = -1;
|
||||||
|
|
||||||
|
if (_.isUndefined(data)) {
|
||||||
|
dlg.dom.dlg_title.html('创建外部密钥');
|
||||||
|
dlg.field_id = -1;
|
||||||
|
dlg.field_acc_key = '';
|
||||||
|
|
||||||
|
dlg.dom.edit_name.val('');
|
||||||
|
dlg.dom.edit_comment.val('');
|
||||||
|
dlg.dom.area_regenerate.hide();
|
||||||
|
} else {
|
||||||
|
dlg.field_id = data.id;
|
||||||
|
dlg.field_acc_key = data.acc_key;
|
||||||
|
dlg.dom.dlg_title.html('编辑外部密钥:<span class="mono">' + data.acc_key + '</span>');
|
||||||
|
|
||||||
|
let _name = $app.role_id2name(data.role_id);
|
||||||
|
if (!_.isUndefined(_name)) {
|
||||||
|
role_name = _name;
|
||||||
|
dlg.field_role = data.role_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlg.dom.edit_name.val(data.name);
|
||||||
|
dlg.dom.edit_comment.val(data.comment);
|
||||||
|
|
||||||
|
dlg.dom.chk_regenerate.prop('checked', false);
|
||||||
|
dlg.dom.area_regenerate.show();
|
||||||
|
}
|
||||||
|
dlg.dom.selected_role.text(role_name);
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.show_create = function () {
|
||||||
|
dlg.init_fields();
|
||||||
|
dlg.dom.dialog.modal({backdrop: 'static'});
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.show_edit = function (row_id) {
|
||||||
|
let data = _obj.table_integration.get_row(row_id);
|
||||||
|
// console.log(data);
|
||||||
|
dlg.init_fields(data);
|
||||||
|
dlg.dom.dialog.modal({backdrop: 'static'});
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.check_input = function () {
|
||||||
|
dlg.field_name = dlg.dom.edit_name.val();
|
||||||
|
dlg.field_comment = dlg.dom.edit_comment.val();
|
||||||
|
|
||||||
|
if (dlg.field_role === -1) {
|
||||||
|
$tp.notify_error('请为外部密钥指定一个权限角色!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dlg.field_name.length === 0) {
|
||||||
|
dlg.dom.edit_name.focus();
|
||||||
|
$tp.notify_error('请为外部密钥设置一个名称!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.on_save = function () {
|
||||||
|
if (!dlg.check_input())
|
||||||
|
return;
|
||||||
|
|
||||||
|
let action = (dlg.field_id === -1) ? '创建' : '更新';
|
||||||
|
let timeout = (dlg.field_id === -1) ? 60000 : 30000;
|
||||||
|
|
||||||
|
let is_regenerate = dlg.dom.chk_regenerate.is(':checked');
|
||||||
|
let args = {
|
||||||
|
id: dlg.field_id,
|
||||||
|
role_id: dlg.field_role,
|
||||||
|
name: dlg.field_name,
|
||||||
|
comment: dlg.field_comment,
|
||||||
|
};
|
||||||
|
if (dlg.field_id !== -1) {
|
||||||
|
args['acc_key'] = dlg.field_acc_key;
|
||||||
|
args['regenerate'] = is_regenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果id为-1表示创建,否则表示更新
|
||||||
|
$tp.ajax_post_json('/system/update-integration', args,
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
if (ret.message.length > 0)
|
||||||
|
$tp.notify_success(ret.message);
|
||||||
|
else
|
||||||
|
$tp.notify_success('外部密钥' + action + '成功!');
|
||||||
|
_obj.table_integration.load_data();
|
||||||
|
dlg.dom.dialog.modal('hide');
|
||||||
|
|
||||||
|
if (dlg.field_id === -1 || is_regenerate) {
|
||||||
|
let msg = [
|
||||||
|
'<div class="alert alert-warning">注意:Access Secret 仅显示一次,请妥善记录!</div><div>',
|
||||||
|
'<p style="padding-top:10px;"><span style="display:inline-block;width:130px;"><i class="fa fa-key fa-fw"></i> Access Key: </span><span class="mono bold">',
|
||||||
|
ret.data.acc_key,
|
||||||
|
'</span></p><p style="padding-top:10px;"><span style="display:inline-block;width:130px;"><i class="fa fa-eye-slash fa-fw"></i> Access Secret: </span><span class="mono bold">',
|
||||||
|
ret.data.acc_sec,
|
||||||
|
'</span></p></div>'
|
||||||
|
];
|
||||||
|
$app.dlg_result.show('外部密钥' + action + '成功', msg.join(''));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('外部密钥' + action + '失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$tp.notify_error('网络故障,外部密钥' + action + '失败!');
|
||||||
|
},
|
||||||
|
timeout
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return dlg;
|
||||||
|
};
|
||||||
|
|
||||||
|
return _obj;
|
||||||
|
};
|
||||||
|
|
|
@ -117,7 +117,7 @@ $tp.create_table = function (options) {
|
||||||
// 整理传入的表格初始化参数
|
// 整理传入的表格初始化参数
|
||||||
_tbl._fix_options = function () {
|
_tbl._fix_options = function () {
|
||||||
if (!_.isUndefined(_tbl.options.column_default)) {
|
if (!_.isUndefined(_tbl.options.column_default)) {
|
||||||
for (var i = 0, cnt = _tbl.options.columns.length; i < cnt; ++i) {
|
for (let i = 0, cnt = _tbl.options.columns.length; i < cnt; ++i) {
|
||||||
if (!_.isUndefined(_tbl.options.columns[i]['align'])) {
|
if (!_.isUndefined(_tbl.options.columns[i]['align'])) {
|
||||||
if (_.isUndefined(_tbl.options.columns[i]['header_align'])) {
|
if (_.isUndefined(_tbl.options.columns[i]['header_align'])) {
|
||||||
_tbl.options.columns[i]['header_align'] = _tbl.options.columns[i]['align'];
|
_tbl.options.columns[i]['header_align'] = _tbl.options.columns[i]['align'];
|
||||||
|
@ -127,7 +127,7 @@ $tp.create_table = function (options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var k in _tbl.options.column_default) {
|
for (let k in _tbl.options.column_default) {
|
||||||
if (_tbl.options.column_default.hasOwnProperty(k)) {
|
if (_tbl.options.column_default.hasOwnProperty(k)) {
|
||||||
if (k === 'align') {
|
if (k === 'align') {
|
||||||
if (_.isUndefined(_tbl.options.columns[i]['header_align'])) {
|
if (_.isUndefined(_tbl.options.columns[i]['header_align'])) {
|
||||||
|
@ -136,8 +136,7 @@ $tp.create_table = function (options) {
|
||||||
if (_.isUndefined(_tbl.options.columns[i]['cell_align'])) {
|
if (_.isUndefined(_tbl.options.columns[i]['cell_align'])) {
|
||||||
_tbl.options.columns[i]['cell_align'] = _tbl.options.column_default[k];
|
_tbl.options.columns[i]['cell_align'] = _tbl.options.column_default[k];
|
||||||
}
|
}
|
||||||
}
|
} else if (_.isUndefined(_tbl.options.columns[i][k])) {
|
||||||
else if (_.isUndefined(_tbl.options.columns[i][k])) {
|
|
||||||
_tbl.options.columns[i][k] = _tbl.options.column_default[k];
|
_tbl.options.columns[i][k] = _tbl.options.column_default[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,28 +229,28 @@ $tp.create_table = function (options) {
|
||||||
|
|
||||||
_tbl.load_begin(1500);
|
_tbl.load_begin(1500);
|
||||||
|
|
||||||
var _filter = {};
|
let _filter = {};
|
||||||
// 对每一个关联的过滤器,获取其设置
|
// 对每一个关联的过滤器,获取其设置
|
||||||
$.each(_tbl.filter_ctrls, function (name, ctrl) {
|
$.each(_tbl.filter_ctrls, function (name, ctrl) {
|
||||||
if (_.isUndefined(ctrl.get_filter)) {
|
if (_.isUndefined(ctrl.get_filter)) {
|
||||||
console.error('filter', name, 'has have no get_filter() interface.');
|
console.error('filter', name, 'has have no get_filter() interface.');
|
||||||
}
|
}
|
||||||
var _f = ctrl.get_filter();
|
let _f = ctrl.get_filter();
|
||||||
$.each(_f, function (k, v) {
|
$.each(_f, function (k, v) {
|
||||||
_filter[k] = v;
|
_filter[k] = v;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var _order = null;
|
let _order = null;
|
||||||
if (_tbl.header_ctrl) {
|
if (_tbl.header_ctrl) {
|
||||||
_order = _tbl.header_ctrl.get_order();
|
_order = _tbl.header_ctrl.get_order();
|
||||||
}
|
}
|
||||||
|
|
||||||
var _limit = {};
|
let _limit = {};
|
||||||
_limit.page_index = _tbl.page_index;
|
_limit.page_index = _tbl.page_index;
|
||||||
_limit.per_page = _tbl.per_page;
|
_limit.per_page = _tbl.per_page;
|
||||||
|
|
||||||
var args = {filter: _filter, order: _order, limit: _limit};
|
let args = {filter: _filter, order: _order, limit: _limit};
|
||||||
if (_tbl.options.data_source && _tbl.options.data_source.restrict)
|
if (_tbl.options.data_source && _tbl.options.data_source.restrict)
|
||||||
args.restrict = _tbl.options.data_source.restrict;
|
args.restrict = _tbl.options.data_source.restrict;
|
||||||
if (_tbl.options.data_source && _tbl.options.data_source.exclude)
|
if (_tbl.options.data_source && _tbl.options.data_source.exclude)
|
||||||
|
@ -265,12 +264,14 @@ $tp.create_table = function (options) {
|
||||||
if (_tbl.options.data_source) {
|
if (_tbl.options.data_source) {
|
||||||
if (_tbl.options.data_source.type === 'none') {
|
if (_tbl.options.data_source.type === 'none') {
|
||||||
// 外部直接调用set_data()方法来设置数据,无需本控件主动获取
|
// 外部直接调用set_data()方法来设置数据,无需本控件主动获取
|
||||||
|
cb_stack.exec();
|
||||||
} else if (_tbl.options.data_source.type === 'callback') {
|
} else if (_tbl.options.data_source.type === 'callback') {
|
||||||
// 调用一个函数来加载数据
|
// 调用一个函数来加载数据
|
||||||
args.table = _tbl;
|
args.table = _tbl;
|
||||||
_tbl.options.data_source.fn(cb_stack, args);
|
_tbl.options.data_source.fn(cb_stack, args);
|
||||||
|
cb_stack.exec();
|
||||||
} else if (_tbl.options.data_source.type === 'ajax-post') {
|
} else if (_tbl.options.data_source.type === 'ajax-post') {
|
||||||
var _url = _tbl.options.data_source.url;
|
let _url = _tbl.options.data_source.url;
|
||||||
$tp.ajax_post_json(_url, args,
|
$tp.ajax_post_json(_url, args,
|
||||||
function (ret) {
|
function (ret) {
|
||||||
// console.log('ajax-return:', ret);
|
// console.log('ajax-return:', ret);
|
||||||
|
@ -281,27 +282,31 @@ $tp.create_table = function (options) {
|
||||||
cb_stack.add(_tbl.load_end);
|
cb_stack.add(_tbl.load_end);
|
||||||
_tbl.set_data(cb_stack, {}, {total: ret.data.total, page_index: ret.data.page_index, data: ret.data.data});
|
_tbl.set_data(cb_stack, {}, {total: ret.data.total, page_index: ret.data.page_index, data: ret.data.data});
|
||||||
}
|
}
|
||||||
|
cb_stack.exec();
|
||||||
},
|
},
|
||||||
function () {
|
function () {
|
||||||
_tbl.show_load_failed();
|
_tbl.show_load_failed();
|
||||||
|
cb_stack.exec();
|
||||||
}, 6000
|
}, 6000
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.error('table-options [data-source] type [' + _tbl.options.data_source.type + '] known.');
|
console.error('table-options [data-source] type [' + _tbl.options.data_source.type + '] known.');
|
||||||
|
cb_stack.exec();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('have no idea for load table data. need data_source.');
|
console.error('have no idea for load table data. need data_source.');
|
||||||
|
cb_stack.exec();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_tbl._create_row_dom = function (row_data) {
|
_tbl._create_row_dom = function (row_data) {
|
||||||
var node = ['<tr data-row-id="' + row_data._row_id + '">'];
|
let node = ['<tr data-row-id="' + row_data._row_id + '">'];
|
||||||
|
|
||||||
for (var i = 0, cnt = _tbl.options.columns.length; i < cnt; ++i) {
|
for (let i = 0, cnt = _tbl.options.columns.length; i < cnt; ++i) {
|
||||||
var col = _tbl.options.columns[i];
|
let col = _tbl.options.columns[i];
|
||||||
node.push('<td data-cell-id="' + row_data._row_id + '-' + i + '"');
|
node.push('<td data-cell-id="' + row_data._row_id + '-' + i + '"');
|
||||||
|
|
||||||
var _style = '';
|
let _style = '';
|
||||||
if (col.cell_align !== 'center') {
|
if (col.cell_align !== 'center') {
|
||||||
_style += 'text-align:' + col.cell_align + ';';
|
_style += 'text-align:' + col.cell_align + ';';
|
||||||
}
|
}
|
||||||
|
@ -314,12 +319,12 @@ $tp.create_table = function (options) {
|
||||||
|
|
||||||
node.push('>');
|
node.push('>');
|
||||||
|
|
||||||
var k;
|
let k;
|
||||||
if (_.isUndefined(col.render)) {
|
if (_.isUndefined(col.render)) {
|
||||||
if (_.isUndefined(col.fields) || _.isEmpty(col.fields)) {
|
if (_.isUndefined(col.fields) || _.isEmpty(col.fields)) {
|
||||||
node.push(row_data[col.key]);
|
node.push(row_data[col.key]);
|
||||||
} else {
|
} else {
|
||||||
var _tmp = [];
|
let _tmp = [];
|
||||||
for (k in col.fields) {
|
for (k in col.fields) {
|
||||||
if (col.fields.hasOwnProperty(k))
|
if (col.fields.hasOwnProperty(k))
|
||||||
_tmp.push(row_data[col.fields[k]]);
|
_tmp.push(row_data[col.fields[k]]);
|
||||||
|
@ -328,7 +333,7 @@ $tp.create_table = function (options) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_.isFunction(_tbl.render[col.render])) {
|
if (_.isFunction(_tbl.render[col.render])) {
|
||||||
var _args = {};
|
let _args = {};
|
||||||
for (k in col.fields) {
|
for (k in col.fields) {
|
||||||
if (col.fields.hasOwnProperty(k))
|
if (col.fields.hasOwnProperty(k))
|
||||||
_args[k] = row_data[col.fields[k]];
|
_args[k] = row_data[col.fields[k]];
|
||||||
|
@ -345,10 +350,10 @@ $tp.create_table = function (options) {
|
||||||
|
|
||||||
_tbl._render_row = function (row_data, pos_row_id) {
|
_tbl._render_row = function (row_data, pos_row_id) {
|
||||||
// 0=插入到第一行,-1=插入到最后一行(默认),其他=插入到指定row_id的行之后,如果没有找到指定的行,则插入到最后
|
// 0=插入到第一行,-1=插入到最后一行(默认),其他=插入到指定row_id的行之后,如果没有找到指定的行,则插入到最后
|
||||||
var _pos = !_.isUndefined(pos_row_id) ? pos_row_id : -1;
|
let _pos = !_.isUndefined(pos_row_id) ? pos_row_id : -1;
|
||||||
|
|
||||||
var dom_obj = $('#' + _tbl.dom_id + ' tbody');
|
let dom_obj = $('#' + _tbl.dom_id + ' tbody');
|
||||||
var _tr = $(_tbl._create_row_dom(row_data));
|
let _tr = $(_tbl._create_row_dom(row_data));
|
||||||
_tr.data('data-row-data', row_data);
|
_tr.data('data-row-data', row_data);
|
||||||
|
|
||||||
if (_pos === -1) {
|
if (_pos === -1) {
|
||||||
|
@ -356,7 +361,7 @@ $tp.create_table = function (options) {
|
||||||
} else if (_pos === 0) {
|
} else if (_pos === 0) {
|
||||||
dom_obj.prepend(_tr);
|
dom_obj.prepend(_tr);
|
||||||
} else {
|
} else {
|
||||||
var _pos_obj = $(dom_obj).find("[data-row-id='" + _pos + "']");
|
let _pos_obj = $(dom_obj).find("[data-row-id='" + _pos + "']");
|
||||||
if (0 === _pos_obj[0]) {
|
if (0 === _pos_obj[0]) {
|
||||||
// 没有找到指定行,则加入到最后
|
// 没有找到指定行,则加入到最后
|
||||||
dom_obj.append(_tr);
|
dom_obj.append(_tr);
|
||||||
|
@ -368,40 +373,40 @@ $tp.create_table = function (options) {
|
||||||
|
|
||||||
// callback for each cell.
|
// callback for each cell.
|
||||||
if (_.isFunction(_tbl.options.on_cell_created)) {
|
if (_.isFunction(_tbl.options.on_cell_created)) {
|
||||||
var _cell_objs = $('#' + _tbl.dom_id + " tr[data-row-id='" + row_data._row_id + "'] td");
|
let _cell_objs = $('#' + _tbl.dom_id + " tr[data-row-id='" + row_data._row_id + "'] td");
|
||||||
for (var i = 0, cnt = _cell_objs.length; i < cnt; ++i) {
|
for (let i = 0, cnt = _cell_objs.length; i < cnt; ++i) {
|
||||||
console.log('aaaa');
|
console.log('aaaa');
|
||||||
_tbl.options.on_cell_created(_tbl, row_data._row_id, _tbl.options.columns[i].key, $(_cell_objs[i]));
|
_tbl.options.on_cell_created(_tbl, row_data._row_id, _tbl.options.columns[i].key, $(_cell_objs[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_.isFunction(_tbl.options.on_row_created)) {
|
if (_.isFunction(_tbl.options.on_row_created)) {
|
||||||
var _row_obj = $('#' + _tbl.dom_id + " [data-row-id='" + row_data._row_id + "']");
|
let _row_obj = $('#' + _tbl.dom_id + " [data-row-id='" + row_data._row_id + "']");
|
||||||
_tbl.options.on_row_created(_tbl, row_data._row_id, _row_obj);
|
_tbl.options.on_row_created(_tbl, row_data._row_id, _row_obj);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
_tbl._render_rows = function (rows_data, pos_row_id) {
|
_tbl._render_rows = function (rows_data, pos_row_id) {
|
||||||
// 0=插入到第一行,-1=插入到最后一行(默认),其他=插入到指定row_id的行之后,如果没有找到指定的行,则插入到最后
|
// 0=插入到第一行,-1=插入到最后一行(默认),其他=插入到指定row_id的行之后,如果没有找到指定的行,则插入到最后
|
||||||
var _pos = !_.isUndefined(pos_row_id) ? pos_row_id : -1;
|
let _pos = !_.isUndefined(pos_row_id) ? pos_row_id : -1;
|
||||||
|
|
||||||
var dom_obj = $('#' + _tbl.dom_id + ' tbody');
|
let dom_obj = $('#' + _tbl.dom_id + ' tbody');
|
||||||
var node = [];
|
let node = [];
|
||||||
|
|
||||||
var r;
|
let r;
|
||||||
var row_count = rows_data.length;
|
let row_count = rows_data.length;
|
||||||
for (r = 0; r < row_count; ++r) {
|
for (r = 0; r < row_count; ++r) {
|
||||||
node.push(_tbl._create_row_dom(rows_data[r]));
|
node.push(_tbl._create_row_dom(rows_data[r]));
|
||||||
}
|
}
|
||||||
|
|
||||||
var _tr = $(node.join(''));
|
let _tr = $(node.join(''));
|
||||||
|
|
||||||
if (_pos === -1) {
|
if (_pos === -1) {
|
||||||
dom_obj.append(_tr);
|
dom_obj.append(_tr);
|
||||||
} else if (_pos === 0) {
|
} else if (_pos === 0) {
|
||||||
dom_obj.prepend(_tr);
|
dom_obj.prepend(_tr);
|
||||||
} else {
|
} else {
|
||||||
var _pos_obj = $(dom_obj).find("[data-row-id='" + _pos + "']");
|
let _pos_obj = $(dom_obj).find("[data-row-id='" + _pos + "']");
|
||||||
if (0 === _pos_obj[0]) {
|
if (0 === _pos_obj[0]) {
|
||||||
// 没有找到指定行,则加入到最后
|
// 没有找到指定行,则加入到最后
|
||||||
dom_obj.append(_tr);
|
dom_obj.append(_tr);
|
||||||
|
@ -411,15 +416,15 @@ $tp.create_table = function (options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _have_cell_created = _.isFunction(_tbl.options.on_cell_created);
|
let _have_cell_created = _.isFunction(_tbl.options.on_cell_created);
|
||||||
var _have_row_created = _.isFunction(_tbl.options.on_row_created);
|
let _have_row_created = _.isFunction(_tbl.options.on_row_created);
|
||||||
|
|
||||||
for (r = 0; r < row_count; ++r) {
|
for (r = 0; r < row_count; ++r) {
|
||||||
var _row_obj = $('#' + _tbl.dom_id + ' tr[data-row-id="' + rows_data[r]._row_id + '"]');
|
let _row_obj = $('#' + _tbl.dom_id + ' tr[data-row-id="' + rows_data[r]._row_id + '"]');
|
||||||
_row_obj.data('data-row-data', rows_data[r]);
|
_row_obj.data('data-row-data', rows_data[r]);
|
||||||
|
|
||||||
if (_have_cell_created) {
|
if (_have_cell_created) {
|
||||||
for (var i = 0, cnt = _tbl.options.columns.length; i < cnt; ++i) {
|
for (let i = 0, cnt = _tbl.options.columns.length; i < cnt; ++i) {
|
||||||
_tbl.options.on_cell_created(_tbl, rows_data[r]._row_id, _tbl.options.columns[i].key, $('#' + _tbl.dom_id + ' td[data-cell-id="' + rows_data[r]._row_id + '-' + i + '"]'));
|
_tbl.options.on_cell_created(_tbl, rows_data[r]._row_id, _tbl.options.columns[i].key, $('#' + _tbl.dom_id + ' td[data-cell-id="' + rows_data[r]._row_id + '-' + i + '"]'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,7 +435,7 @@ $tp.create_table = function (options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tbl.render_table = function (cb_stack, cb_args) {
|
_tbl.render_table = function (cb_stack, cb_args) {
|
||||||
var dom_obj = $('#' + _tbl.dom_id + ' tbody');
|
let dom_obj = $('#' + _tbl.dom_id + ' tbody');
|
||||||
|
|
||||||
if (_tbl.row_data.length === 0) {
|
if (_tbl.row_data.length === 0) {
|
||||||
_tbl.show_empty_table();
|
_tbl.show_empty_table();
|
||||||
|
@ -452,7 +457,7 @@ $tp.create_table = function (options) {
|
||||||
_tbl.page_total = Math.ceil(_tbl.total / _tbl.per_page);
|
_tbl.page_total = Math.ceil(_tbl.total / _tbl.per_page);
|
||||||
|
|
||||||
// 我们为表格的每一行数据加入我们自己的索引 _row_id
|
// 我们为表格的每一行数据加入我们自己的索引 _row_id
|
||||||
for (var i = 0, cnt = _tbl.row_data.length; i < cnt; ++i) {
|
for (let i = 0, cnt = _tbl.row_data.length; i < cnt; ++i) {
|
||||||
if (_.isUndefined(_tbl.row_data[i]._row_id)) {
|
if (_.isUndefined(_tbl.row_data[i]._row_id)) {
|
||||||
_tbl.row_data[i]._row_id = _.uniqueId();
|
_tbl.row_data[i]._row_id = _.uniqueId();
|
||||||
}
|
}
|
||||||
|
@ -474,9 +479,9 @@ $tp.create_table = function (options) {
|
||||||
// 2. 行本身的JQuery对象,或者行内任意一个JQuery对象
|
// 2. 行本身的JQuery对象,或者行内任意一个JQuery对象
|
||||||
// 3. 行的id(创建行时内部制定的,不一定是顺序号)
|
// 3. 行的id(创建行时内部制定的,不一定是顺序号)
|
||||||
_tbl.get_row = function (obj) {
|
_tbl.get_row = function (obj) {
|
||||||
var _tr = null;
|
let _tr = null;
|
||||||
if (_.isElement(obj) || _.isObject(obj)) {
|
if (_.isElement(obj) || _.isObject(obj)) {
|
||||||
var _obj = _.isElement(obj) ? $(obj) : obj;
|
let _obj = _.isElement(obj) ? $(obj) : obj;
|
||||||
if (_obj.prop('tagName') === 'TR') {
|
if (_obj.prop('tagName') === 'TR') {
|
||||||
_tr = _obj;
|
_tr = _obj;
|
||||||
} else if (_obj.prop('tagName') === 'TD') {
|
} else if (_obj.prop('tagName') === 'TD') {
|
||||||
|
@ -486,8 +491,8 @@ $tp.create_table = function (options) {
|
||||||
}
|
}
|
||||||
return _tr.data('data-row-data');
|
return _tr.data('data-row-data');
|
||||||
} else if (_.isString(obj) || _.isNumber(obj)) {
|
} else if (_.isString(obj) || _.isNumber(obj)) {
|
||||||
var _id = _.isString(obj) ? obj : '' + obj;
|
let _id = _.isString(obj) ? obj : '' + obj;
|
||||||
for (var i = 0, cnt = _tbl.row_data.length; i < cnt; ++i) {
|
for (let i = 0, cnt = _tbl.row_data.length; i < cnt; ++i) {
|
||||||
if (_tbl.row_data[i]._row_id === _id) {
|
if (_tbl.row_data[i]._row_id === _id) {
|
||||||
return _tbl.row_data[i];
|
return _tbl.row_data[i];
|
||||||
}
|
}
|
||||||
|
@ -502,10 +507,10 @@ $tp.create_table = function (options) {
|
||||||
// TODO: 更新一行数据,传入的kv有可能比原始数据内容的字段更多,需要能够保存下来备用
|
// TODO: 更新一行数据,传入的kv有可能比原始数据内容的字段更多,需要能够保存下来备用
|
||||||
// TODO: 此外,需要检查一下表格初始化时使用的字段,如果这些字段的内容并没有更新,则无需更新界面元素,以提升性能
|
// TODO: 此外,需要检查一下表格初始化时使用的字段,如果这些字段的内容并没有更新,则无需更新界面元素,以提升性能
|
||||||
_tbl.update_row = function (row_id, kv) {
|
_tbl.update_row = function (row_id, kv) {
|
||||||
var _row_obj = $('#' + _tbl.dom_id + " tr[data-row-id='" + row_id + "']");
|
let _row_obj = $('#' + _tbl.dom_id + " tr[data-row-id='" + row_id + "']");
|
||||||
var _row_data = _row_obj.data('data-row-data');
|
let _row_data = _row_obj.data('data-row-data');
|
||||||
var _changed_fields = [];
|
let _changed_fields = [];
|
||||||
for (var k in kv) {
|
for (let k in kv) {
|
||||||
if (kv.hasOwnProperty(k)) {
|
if (kv.hasOwnProperty(k)) {
|
||||||
if (!_.isUndefined(_row_data[k])) {
|
if (!_.isUndefined(_row_data[k])) {
|
||||||
if (_row_data[k] !== kv[k])
|
if (_row_data[k] !== kv[k])
|
||||||
|
@ -523,10 +528,10 @@ $tp.create_table = function (options) {
|
||||||
console.log('-- update row ui --');
|
console.log('-- update row ui --');
|
||||||
|
|
||||||
// 根据columns的设置,更新界面元素
|
// 根据columns的设置,更新界面元素
|
||||||
for (var i in _tbl.options.columns) {
|
for (let i in _tbl.options.columns) {
|
||||||
if (!_tbl.options.columns.hasOwnProperty(i))
|
if (!_tbl.options.columns.hasOwnProperty(i))
|
||||||
continue;
|
continue;
|
||||||
var col = _tbl.options.columns[i];
|
let col = _tbl.options.columns[i];
|
||||||
for (k in kv) {
|
for (k in kv) {
|
||||||
if (!kv.hasOwnProperty(k))
|
if (!kv.hasOwnProperty(k))
|
||||||
continue;
|
continue;
|
||||||
|
@ -535,17 +540,17 @@ $tp.create_table = function (options) {
|
||||||
|
|
||||||
if (_.contains(col.fields, k)) {
|
if (_.contains(col.fields, k)) {
|
||||||
|
|
||||||
var _cell = $('#' + _tbl.dom_id + ' td[data-cell-id="' + row_id + '-' + i + '"]');
|
let _cell = $('#' + _tbl.dom_id + ' td[data-cell-id="' + row_id + '-' + i + '"]');
|
||||||
|
|
||||||
if (col.recreate) {
|
if (col.recreate) {
|
||||||
if (_.isFunction(_tbl.options.on_cell_created)) {
|
if (_.isFunction(_tbl.options.on_cell_created)) {
|
||||||
var node = '';
|
let node = '';
|
||||||
if (_.isUndefined(col.render)) {
|
if (_.isUndefined(col.render)) {
|
||||||
node += _row_data[col.key];
|
node += _row_data[col.key];
|
||||||
} else {
|
} else {
|
||||||
if (_.isFunction(_tbl.render[col.render])) {
|
if (_.isFunction(_tbl.render[col.render])) {
|
||||||
var _args = {};
|
let _args = {};
|
||||||
for (var f in col.fields) {
|
for (let f in col.fields) {
|
||||||
if (col.fields.hasOwnProperty(f))
|
if (col.fields.hasOwnProperty(f))
|
||||||
_args[f] = _row_data[col.fields[f]];
|
_args[f] = _row_data[col.fields[f]];
|
||||||
}
|
}
|
||||||
|
@ -579,13 +584,13 @@ $tp.create_table = function (options) {
|
||||||
|
|
||||||
// 参数pos_row_id: 0=插入到第一行,-1=插入到最后一行(默认),其他=插入到指定row_id的行之后,如果没有找到指定的行,则插入到最后
|
// 参数pos_row_id: 0=插入到第一行,-1=插入到最后一行(默认),其他=插入到指定row_id的行之后,如果没有找到指定的行,则插入到最后
|
||||||
_tbl.add_row = function (rows, pos_row_id, fn_is_duplicated) {
|
_tbl.add_row = function (rows, pos_row_id, fn_is_duplicated) {
|
||||||
var ret_row_id = [];
|
let ret_row_id = [];
|
||||||
var _fn = _.isFunction(fn_is_duplicated) ? fn_is_duplicated : null;
|
let _fn = _.isFunction(fn_is_duplicated) ? fn_is_duplicated : null;
|
||||||
var _new_count = rows.length;
|
let _new_count = rows.length;
|
||||||
for (var i = 0; i < _new_count; ++i) {
|
for (let i = 0; i < _new_count; ++i) {
|
||||||
var _my_count = _tbl.row_data.length;
|
let _my_count = _tbl.row_data.length;
|
||||||
var _is_duplicated = false;
|
let _is_duplicated = false;
|
||||||
for (var j = 0; j < _my_count; ++j) {
|
for (let j = 0; j < _my_count; ++j) {
|
||||||
if (_fn) {
|
if (_fn) {
|
||||||
if (_fn(rows[i], _tbl.row_data[j])) {
|
if (_fn(rows[i], _tbl.row_data[j])) {
|
||||||
_is_duplicated = true;
|
_is_duplicated = true;
|
||||||
|
@ -617,8 +622,8 @@ $tp.create_table = function (options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tbl.remove_row = function (row_id) {
|
_tbl.remove_row = function (row_id) {
|
||||||
var _index = -1;
|
let _index = -1;
|
||||||
for (var i = 0, cnt = _tbl.row_data.length; i < cnt; ++i) {
|
for (let i = 0, cnt = _tbl.row_data.length; i < cnt; ++i) {
|
||||||
if (_tbl.row_data[i]['_row_id'] === row_id) {
|
if (_tbl.row_data[i]['_row_id'] === row_id) {
|
||||||
_index = i;
|
_index = i;
|
||||||
break;
|
break;
|
||||||
|
@ -637,7 +642,7 @@ $tp.create_table = function (options) {
|
||||||
_tbl.clear = function () {
|
_tbl.clear = function () {
|
||||||
$('#' + _tbl.dom_id + ' tbody').empty();
|
$('#' + _tbl.dom_id + ' tbody').empty();
|
||||||
_tbl.row_data = [];
|
_tbl.row_data = [];
|
||||||
var cb_stack = CALLBACK_STACK.create();
|
let cb_stack = CALLBACK_STACK.create();
|
||||||
cb_stack
|
cb_stack
|
||||||
.add(_tbl.on_data_loaded)
|
.add(_tbl.on_data_loaded)
|
||||||
.add(_tbl.update_paging)
|
.add(_tbl.update_paging)
|
||||||
|
@ -649,7 +654,7 @@ $tp.create_table = function (options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tbl.load_begin = function (delay_) {
|
_tbl.load_begin = function (delay_) {
|
||||||
var _delay = delay_ || 1000;
|
let _delay = delay_ || 1000;
|
||||||
_tbl.show_loading(_delay);
|
_tbl.show_loading(_delay);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -663,7 +668,7 @@ $tp.create_table = function (options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tbl.show_loading = function (delay_) {
|
_tbl.show_loading = function (delay_) {
|
||||||
var _delay = delay_ || 0;
|
let _delay = delay_ || 0;
|
||||||
if (_delay > 0) {
|
if (_delay > 0) {
|
||||||
if (_tbl.loading_timer === null) {
|
if (_tbl.loading_timer === null) {
|
||||||
_tbl.loading_timer = setTimeout(function () {
|
_tbl.loading_timer = setTimeout(function () {
|
||||||
|
@ -673,7 +678,7 @@ $tp.create_table = function (options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg_loading = '<tr role="row"><td class="loading" colspan="' + _tbl.column_count + '" style="text-align:center;"><i class="fa fa-circle-o-notch fa-spin"></i> 加载中,请稍候...</td></tr>';
|
let msg_loading = '<tr role="row"><td class="loading" colspan="' + _tbl.column_count + '" style="text-align:center;"><i class="fa fa-circle-o-notch fa-spin"></i> 加载中,请稍候...</td></tr>';
|
||||||
$('#' + _tbl.dom_id + ' tbody').prepend($(msg_loading))
|
$('#' + _tbl.dom_id + ' tbody').prepend($(msg_loading))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -683,7 +688,7 @@ $tp.create_table = function (options) {
|
||||||
_tbl.loading_timer = null;
|
_tbl.loading_timer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg_loading = '<tr><td class="loading" colspan="' + _tbl.column_count + '" style="text-align:center;background-color:#f0d4d2;"><i class="fas fa-exclamation-triangle fa-fw"></i> 糟糕!加载失败了...</td></tr>';
|
let msg_loading = '<tr><td class="loading" colspan="' + _tbl.column_count + '" style="text-align:center;background-color:#f0d4d2;"><i class="fas fa-exclamation-triangle fa-fw"></i> 糟糕!加载失败了...</td></tr>';
|
||||||
$('#' + _tbl.dom_id + ' tbody').empty().append($(msg_loading))
|
$('#' + _tbl.dom_id + ' tbody').empty().append($(msg_loading))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -693,11 +698,11 @@ $tp.create_table = function (options) {
|
||||||
_tbl.loading_timer = null;
|
_tbl.loading_timer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// var msg = '哇哦,没有数据哦...';
|
// let msg = '哇哦,没有数据哦...';
|
||||||
// if(_tbl.options.message_no_data)
|
// if(_tbl.options.message_no_data)
|
||||||
var msg = _tbl.options.message_no_data || '哇哦,没有数据哦...';
|
let msg = _tbl.options.message_no_data || '哇哦,没有数据哦...';
|
||||||
|
|
||||||
var msg_loading = '<tr><td class="loading" colspan="' + _tbl.column_count + '" style="text-align:center;"><i class="fa fa-info-circle fa-fw"></i> ' + msg + '</td></tr>';
|
let msg_loading = '<tr><td class="loading" colspan="' + _tbl.column_count + '" style="text-align:center;"><i class="fa fa-info-circle fa-fw"></i> ' + msg + '</td></tr>';
|
||||||
$('#' + _tbl.dom_id + ' tbody').empty().append($(msg_loading))
|
$('#' + _tbl.dom_id + ' tbody').empty().append($(msg_loading))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -728,7 +733,7 @@ $tp.create_table = function (options) {
|
||||||
// TODO: to create fixed header (not scroll), see https://github.com/markmalek/Fixed-Header-Table
|
// TODO: to create fixed header (not scroll), see https://github.com/markmalek/Fixed-Header-Table
|
||||||
|
|
||||||
$tp.create_table_header = function (tbl, on_created) {
|
$tp.create_table_header = function (tbl, on_created) {
|
||||||
var _tbl_header = {};
|
let _tbl_header = {};
|
||||||
|
|
||||||
_tbl_header.dom_id = tbl.dom_id;
|
_tbl_header.dom_id = tbl.dom_id;
|
||||||
_tbl_header._table_ctrl = tbl;
|
_tbl_header._table_ctrl = tbl;
|
||||||
|
@ -752,9 +757,9 @@ $tp.create_table_header = function (tbl, on_created) {
|
||||||
_tbl_header.order_by = '';
|
_tbl_header.order_by = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
var _first_sort = '';
|
let _first_sort = '';
|
||||||
var _sort_asc = true;
|
let _sort_asc = true;
|
||||||
var _found = false;
|
let _found = false;
|
||||||
$.each(_tbl_header._columns, function (i, col) {
|
$.each(_tbl_header._columns, function (i, col) {
|
||||||
if (col.sort) {
|
if (col.sort) {
|
||||||
if (_first_sort === '') {
|
if (_first_sort === '') {
|
||||||
|
@ -778,10 +783,10 @@ $tp.create_table_header = function (tbl, on_created) {
|
||||||
_tbl_header.order_asc = _sort_asc;
|
_tbl_header.order_asc = _sort_asc;
|
||||||
|
|
||||||
// 创建表格头
|
// 创建表格头
|
||||||
var _dom = ['<thead><tr>'];
|
let _dom = ['<thead><tr>'];
|
||||||
$.each(_tbl_header._columns, function (i, col) {
|
$.each(_tbl_header._columns, function (i, col) {
|
||||||
_dom.push('<th');
|
_dom.push('<th');
|
||||||
var _style = '';
|
let _style = '';
|
||||||
if (col.header_align !== 'center') {
|
if (col.header_align !== 'center') {
|
||||||
_style += 'text-align:' + col.header_align + ';';
|
_style += 'text-align:' + col.header_align + ';';
|
||||||
}
|
}
|
||||||
|
@ -793,7 +798,7 @@ $tp.create_table_header = function (tbl, on_created) {
|
||||||
|
|
||||||
_dom.push('>');
|
_dom.push('>');
|
||||||
|
|
||||||
var _title = ['<span data-col-key="' + col.key + '"'];
|
let _title = ['<span data-col-key="' + col.key + '"'];
|
||||||
if (col.sort) {
|
if (col.sort) {
|
||||||
_title.push(' class="');
|
_title.push(' class="');
|
||||||
if (_tbl_header.order_by === col.key) {
|
if (_tbl_header.order_by === col.key) {
|
||||||
|
@ -842,13 +847,13 @@ $tp.create_table_header = function (tbl, on_created) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tbl_header.click_header = function () {
|
_tbl_header.click_header = function () {
|
||||||
var t = $(this).attr('data-col-key');
|
let t = $(this).attr('data-col-key');
|
||||||
_tbl_header.on_head_click(t);
|
_tbl_header.on_head_click(t);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 点击表格分栏,默认操作为按此栏进行升序/降序排序
|
// 点击表格分栏,默认操作为按此栏进行升序/降序排序
|
||||||
_tbl_header.on_head_click = function (col_key) {
|
_tbl_header.on_head_click = function (col_key) {
|
||||||
var i = 0;
|
let i = 0;
|
||||||
|
|
||||||
if (col_key === _tbl_header.order_by) {
|
if (col_key === _tbl_header.order_by) {
|
||||||
if (_tbl_header.order_asc) {
|
if (_tbl_header.order_asc) {
|
||||||
|
@ -861,12 +866,12 @@ $tp.create_table_header = function (tbl, on_created) {
|
||||||
$('#' + _tbl_header.dom_id + ' th .sorting_asc').removeClass('sorting_asc').addClass('sorting');
|
$('#' + _tbl_header.dom_id + ' th .sorting_asc').removeClass('sorting_asc').addClass('sorting');
|
||||||
$('#' + _tbl_header.dom_id + ' th .sorting_desc').removeClass('sorting_desc').addClass('sorting');
|
$('#' + _tbl_header.dom_id + ' th .sorting_desc').removeClass('sorting_desc').addClass('sorting');
|
||||||
|
|
||||||
var sort_obj = $('#' + _tbl_header.dom_id + " [data-col-key='" + col_key + "']");
|
let sort_obj = $('#' + _tbl_header.dom_id + " [data-col-key='" + col_key + "']");
|
||||||
sort_obj.removeClass('sorting').addClass('sorting_asc');
|
sort_obj.removeClass('sorting').addClass('sorting_asc');
|
||||||
|
|
||||||
_tbl_header.order_by = col_key;
|
_tbl_header.order_by = col_key;
|
||||||
|
|
||||||
var order_asc = true;
|
let order_asc = true;
|
||||||
|
|
||||||
for (i = 0; i < _tbl_header._table_ctrl.column_count; ++i) {
|
for (i = 0; i < _tbl_header._table_ctrl.column_count; ++i) {
|
||||||
if (_tbl_header._table_ctrl.options.columns[i].key === col_key) {
|
if (_tbl_header._table_ctrl.options.columns[i].key === col_key) {
|
||||||
|
@ -884,14 +889,14 @@ $tp.create_table_header = function (tbl, on_created) {
|
||||||
_tbl_header.order_asc = order_asc;
|
_tbl_header.order_asc = order_asc;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cb_stack = CALLBACK_STACK.create();
|
let cb_stack = CALLBACK_STACK.create();
|
||||||
if (_tbl_header._table_ctrl.options.sort === 'local') {
|
if (_tbl_header._table_ctrl.options.sort === 'local') {
|
||||||
console.log('sort-by:', col_key);
|
console.log('sort-by:', col_key);
|
||||||
var data = _.sortBy(_tbl_header._table_ctrl.row_data, col_key);
|
let data = _.sortBy(_tbl_header._table_ctrl.row_data, col_key);
|
||||||
if (_tbl_header.order_asc) {
|
if (_tbl_header.order_asc) {
|
||||||
_tbl_header._table_ctrl.set_data(cb_stack, {}, {data: data});
|
_tbl_header._table_ctrl.set_data(cb_stack, {}, {data: data});
|
||||||
} else {
|
} else {
|
||||||
var tmp = [];
|
let tmp = [];
|
||||||
for (i = data.length - 1; i >= 0; --i) {
|
for (i = data.length - 1; i >= 0; --i) {
|
||||||
tmp.push(data[i]);
|
tmp.push(data[i]);
|
||||||
}
|
}
|
||||||
|
@ -910,7 +915,7 @@ $tp.create_table_header = function (tbl, on_created) {
|
||||||
|
|
||||||
$tp.create_table_render = function (tbl, on_created) {
|
$tp.create_table_render = function (tbl, on_created) {
|
||||||
// console.log('create_table_render', tbl, on_created);
|
// console.log('create_table_render', tbl, on_created);
|
||||||
var _tbl_render = {};
|
let _tbl_render = {};
|
||||||
|
|
||||||
_tbl_render.fs_size = function (row_id, fields) {
|
_tbl_render.fs_size = function (row_id, fields) {
|
||||||
if (fields.type === 0 || fields.type === 2)
|
if (fields.type === 0 || fields.type === 2)
|
||||||
|
@ -931,7 +936,7 @@ $tp.create_table_render = function (tbl, on_created) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tbl_render.host_id = function (row_id, fields) {
|
_tbl_render.host_id = function (row_id, fields) {
|
||||||
var ret = '';
|
let ret = '';
|
||||||
ret = '<span class="host-id">' + fields.id + '</span>';
|
ret = '<span class="host-id">' + fields.id + '</span>';
|
||||||
ret += '<span class="host-desc">' + fields.desc + '</span>';
|
ret += '<span class="host-desc">' + fields.desc + '</span>';
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -980,7 +985,7 @@ $tp.create_table_render = function (tbl, on_created) {
|
||||||
};
|
};
|
||||||
|
|
||||||
$tp.create_table_paging = function (tbl, dom_id, options) {
|
$tp.create_table_paging = function (tbl, dom_id, options) {
|
||||||
var _tblp = {};
|
let _tblp = {};
|
||||||
_tblp._table_ctrl = tbl;
|
_tblp._table_ctrl = tbl;
|
||||||
tbl.paging_ctrl = _tblp;
|
tbl.paging_ctrl = _tblp;
|
||||||
_tblp.dom_id = dom_id;
|
_tblp.dom_id = dom_id;
|
||||||
|
@ -1000,8 +1005,8 @@ $tp.create_table_paging = function (tbl, dom_id, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblp.init = function (cb_stack) {
|
_tblp.init = function (cb_stack) {
|
||||||
var _def_per_page = -1;
|
let _def_per_page = -1;
|
||||||
var _per_page = -1;
|
let _per_page = -1;
|
||||||
$.each(_tblp.options.paging_selector.selections, function (i, s) {
|
$.each(_tblp.options.paging_selector.selections, function (i, s) {
|
||||||
if (s.name === _tblp.options.paging_selector.default_select)
|
if (s.name === _tblp.options.paging_selector.default_select)
|
||||||
_def_per_page = s.val;
|
_def_per_page = s.val;
|
||||||
|
@ -1015,7 +1020,7 @@ $tp.create_table_paging = function (tbl, dom_id, options) {
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
// create DOM
|
// create DOM
|
||||||
//------------------------------------------------
|
//------------------------------------------------
|
||||||
var dom = [];
|
let dom = [];
|
||||||
dom.push('<li><i class="fa fa-list fa-fw"></i> 记录总数 <span data-field="recorder_total">0</span></li>');
|
dom.push('<li><i class="fa fa-list fa-fw"></i> 记录总数 <span data-field="recorder_total">0</span></li>');
|
||||||
dom.push('<li>页数 <span data-field="page_current">1</span>/<span data-field="page_total">0</span></li>');
|
dom.push('<li>页数 <span data-field="page_current">1</span>/<span data-field="page_total">0</span></li>');
|
||||||
dom.push('<li data-field="jump">跳转到第 <input data-field="jump-to-page" type="text" class="form-control form-control-sm" style="display:inline-block;width:3em;padding:1px 5px;" /> 页</li>');
|
dom.push('<li data-field="jump">跳转到第 <input data-field="jump-to-page" type="text" class="form-control form-control-sm" style="display:inline-block;width:3em;padding:1px 5px;" /> 页</li>');
|
||||||
|
@ -1032,7 +1037,7 @@ $tp.create_table_paging = function (tbl, dom_id, options) {
|
||||||
// 绑定事件(输入页码跳转)
|
// 绑定事件(输入页码跳转)
|
||||||
$('#' + _tblp.dom_id + ' [data-field="jump-to-page"]').keydown(function (event) {
|
$('#' + _tblp.dom_id + ' [data-field="jump-to-page"]').keydown(function (event) {
|
||||||
if (event.which === 13) {
|
if (event.which === 13) {
|
||||||
var _val = parseInt($(this).val());
|
let _val = parseInt($(this).val());
|
||||||
if (_val === _tblp.page_current)
|
if (_val === _tblp.page_current)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1042,12 +1047,12 @@ $tp.create_table_paging = function (tbl, dom_id, options) {
|
||||||
|
|
||||||
// 绑定事件(选择每页显示的记录数)
|
// 绑定事件(选择每页显示的记录数)
|
||||||
$('#' + _tblp.dom_id + ' li a[data-tp-selector]').click(function () {
|
$('#' + _tblp.dom_id + ' li a[data-tp-selector]').click(function () {
|
||||||
var select = parseInt($(this).attr('data-tp-selector'));
|
let select = parseInt($(this).attr('data-tp-selector'));
|
||||||
if (_tblp.per_page === select)
|
if (_tblp.per_page === select)
|
||||||
return;
|
return;
|
||||||
_tblp.per_page = select;
|
_tblp.per_page = select;
|
||||||
|
|
||||||
var name = '';
|
let name = '';
|
||||||
$.each(_tblp.options.paging_selector.selections, function (i, p) {
|
$.each(_tblp.options.paging_selector.selections, function (i, p) {
|
||||||
if (p.val === select) {
|
if (p.val === select) {
|
||||||
name = p.name;
|
name = p.name;
|
||||||
|
@ -1074,9 +1079,9 @@ $tp.create_table_paging = function (tbl, dom_id, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblp.update = function (cb_stack) {
|
_tblp.update = function (cb_stack) {
|
||||||
var _total = _tblp._table_ctrl.total || 0;
|
let _total = _tblp._table_ctrl.total || 0;
|
||||||
var _page_index = _tblp._table_ctrl.page_index || 0;
|
let _page_index = _tblp._table_ctrl.page_index || 0;
|
||||||
var _page_total = _tblp._table_ctrl.page_total || 0;
|
let _page_total = _tblp._table_ctrl.page_total || 0;
|
||||||
|
|
||||||
if (_total > 0)
|
if (_total > 0)
|
||||||
_page_index += 1;
|
_page_index += 1;
|
||||||
|
@ -1101,7 +1106,7 @@ $tp.create_table_paging = function (tbl, dom_id, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
$tp.create_table_pagination = function (tbl, dom_id, options) {
|
$tp.create_table_pagination = function (tbl, dom_id, options) {
|
||||||
var _tblp = {};
|
let _tblp = {};
|
||||||
_tblp._table_ctrl = tbl;
|
_tblp._table_ctrl = tbl;
|
||||||
tbl.pagination_ctrl = _tblp;
|
tbl.pagination_ctrl = _tblp;
|
||||||
_tblp.dom_id = dom_id;
|
_tblp.dom_id = dom_id;
|
||||||
|
@ -1114,8 +1119,8 @@ $tp.create_table_pagination = function (tbl, dom_id, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblp.update = function (cb_stack) {
|
_tblp.update = function (cb_stack) {
|
||||||
var _page_index = _tblp._table_ctrl.page_index || 0;
|
let _page_index = _tblp._table_ctrl.page_index || 0;
|
||||||
var _page_total = _tblp._table_ctrl.page_total || 0;
|
let _page_total = _tblp._table_ctrl.page_total || 0;
|
||||||
|
|
||||||
// 如果只有一页,就没必要显示分页跳转器了。
|
// 如果只有一页,就没必要显示分页跳转器了。
|
||||||
if (_page_total < 2) {
|
if (_page_total < 2) {
|
||||||
|
@ -1124,17 +1129,17 @@ $tp.create_table_pagination = function (tbl, dom_id, options) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var node = [];
|
let node = [];
|
||||||
|
|
||||||
// 分页显示规则:
|
// 分页显示规则:
|
||||||
// 总页数小于等于9的,全部显示
|
// 总页数小于等于9的,全部显示
|
||||||
// 总页数大于9的,部分显示
|
// 总页数大于9的,部分显示
|
||||||
// 第一页 上一页 ... x-4 x-3 x-2 x-1 x x+1 x+2 x+3 x+4 ... 下一页 最后一页
|
// 第一页 上一页 ... x-4 x-3 x-2 x-1 x x+1 x+2 x+3 x+4 ... 下一页 最后一页
|
||||||
|
|
||||||
var _start = _page_index - 4;
|
let _start = _page_index - 4;
|
||||||
if (_start < 0)
|
if (_start < 0)
|
||||||
_start = 0;
|
_start = 0;
|
||||||
var _end = _start + 9;
|
let _end = _start + 9;
|
||||||
if (_end > _page_total)
|
if (_end > _page_total)
|
||||||
_end = _page_total;
|
_end = _page_total;
|
||||||
|
|
||||||
|
@ -1154,7 +1159,7 @@ $tp.create_table_pagination = function (tbl, dom_id, options) {
|
||||||
node.push('<li class="disabled"><span><i class="fa fa-ellipsis-h fa-fw"></i></span></li>');
|
node.push('<li class="disabled"><span><i class="fa fa-ellipsis-h fa-fw"></i></span></li>');
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = _start; i < _end; ++i) {
|
for (let i = _start; i < _end; ++i) {
|
||||||
if (i === _page_index)
|
if (i === _page_index)
|
||||||
node.push('<li class="disabled"><span><strong>' + (i + 1) + '</strong></span></li>');
|
node.push('<li class="disabled"><span><strong>' + (i + 1) + '</strong></span></li>');
|
||||||
else
|
else
|
||||||
|
@ -1184,7 +1189,7 @@ $tp.create_table_pagination = function (tbl, dom_id, options) {
|
||||||
|
|
||||||
// 事件绑定
|
// 事件绑定
|
||||||
$('#' + _tblp.dom_id + " [data-jump-to]").click(function () {
|
$('#' + _tblp.dom_id + " [data-jump-to]").click(function () {
|
||||||
var _page_index = parseInt($(this).attr('data-jump-to'));
|
let _page_index = parseInt($(this).attr('data-jump-to'));
|
||||||
_tblp._table_ctrl.paging_jump(_page_index);
|
_tblp._table_ctrl.paging_jump(_page_index);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1199,7 +1204,7 @@ $tp.create_table_pagination = function (tbl, dom_id, options) {
|
||||||
//==============================================================
|
//==============================================================
|
||||||
|
|
||||||
$tp.create_table_filter_fixed_value = function (tbl, key_value_map) {
|
$tp.create_table_filter_fixed_value = function (tbl, key_value_map) {
|
||||||
var _tblf = {};
|
let _tblf = {};
|
||||||
_tblf._table_ctrl = tbl;
|
_tblf._table_ctrl = tbl;
|
||||||
_tblf.name = _.uniqueId('tbl_kv_filter_');
|
_tblf.name = _.uniqueId('tbl_kv_filter_');
|
||||||
_tblf.kvs = key_value_map;
|
_tblf.kvs = key_value_map;
|
||||||
|
@ -1212,7 +1217,7 @@ $tp.create_table_filter_fixed_value = function (tbl, key_value_map) {
|
||||||
};
|
};
|
||||||
|
|
||||||
$tp.create_table_header_filter_search = function (tbl, options) {
|
$tp.create_table_header_filter_search = function (tbl, options) {
|
||||||
var _tblf = {};
|
let _tblf = {};
|
||||||
_tblf._table_ctrl = tbl;
|
_tblf._table_ctrl = tbl;
|
||||||
_tblf.options = options;
|
_tblf.options = options;
|
||||||
|
|
||||||
|
@ -1229,8 +1234,8 @@ $tp.create_table_header_filter_search = function (tbl, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblf.get_filter = function () {
|
_tblf.get_filter = function () {
|
||||||
var _ret = {};
|
let _ret = {};
|
||||||
var _val = $('#' + _tblf.dom_id).val();
|
let _val = $('#' + _tblf.dom_id).val();
|
||||||
if (_.isUndefined(_val) || _val.length === 0)
|
if (_.isUndefined(_val) || _val.length === 0)
|
||||||
return _ret;
|
return _ret;
|
||||||
|
|
||||||
|
@ -1244,7 +1249,7 @@ $tp.create_table_header_filter_search = function (tbl, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblf.render = function () {
|
_tblf.render = function () {
|
||||||
var _ret = [];
|
let _ret = [];
|
||||||
_ret.push('<div class="search-input"><div class="input-group">');
|
_ret.push('<div class="search-input"><div class="input-group">');
|
||||||
_ret.push('<span class="input-group-addon"><i class="fa fa-search fa-fw"></i></span>');
|
_ret.push('<span class="input-group-addon"><i class="fa fa-search fa-fw"></i></span>');
|
||||||
_ret.push('<input id="' + _tblf.dom_id + '" type="text" class="form-control" placeholder="' + _tblf.options.place_holder + '">');
|
_ret.push('<input id="' + _tblf.dom_id + '" type="text" class="form-control" placeholder="' + _tblf.options.place_holder + '">');
|
||||||
|
@ -1256,7 +1261,7 @@ $tp.create_table_header_filter_search = function (tbl, options) {
|
||||||
_tblf.on_created = function () {
|
_tblf.on_created = function () {
|
||||||
$('#' + _tblf.dom_id).keydown(function (event) {
|
$('#' + _tblf.dom_id).keydown(function (event) {
|
||||||
if (event.which === 13) {
|
if (event.which === 13) {
|
||||||
var _val = $(this).val();
|
let _val = $(this).val();
|
||||||
if (_val === _tblf.filter_value)
|
if (_val === _tblf.filter_value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1268,7 +1273,7 @@ $tp.create_table_header_filter_search = function (tbl, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
$tp.create_table_filter_role = function (tbl, roles) {
|
$tp.create_table_filter_role = function (tbl, roles) {
|
||||||
var _tblf = {};
|
let _tblf = {};
|
||||||
_tblf._table_ctrl = tbl;
|
_tblf._table_ctrl = tbl;
|
||||||
_tblf.dom_id = tbl.dom_id + '-filter-role';
|
_tblf.dom_id = tbl.dom_id + '-filter-role';
|
||||||
_tblf.name = 'role';
|
_tblf.name = 'role';
|
||||||
|
@ -1289,13 +1294,13 @@ $tp.create_table_filter_role = function (tbl, roles) {
|
||||||
|
|
||||||
_tblf.reset = function (cb_stack) {
|
_tblf.reset = function (cb_stack) {
|
||||||
_tblf.filter_value = _tblf.default_value;
|
_tblf.filter_value = _tblf.default_value;
|
||||||
var name = _tblf._id2name(_tblf.filter_value);
|
let name = _tblf._id2name(_tblf.filter_value);
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
cb_stack.exec();
|
cb_stack.exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblf.render = function () {
|
_tblf.render = function () {
|
||||||
var _ret = [];
|
let _ret = [];
|
||||||
_ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select">');
|
_ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select">');
|
||||||
_ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
_ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
||||||
_ret.push('<span data-tp-select-result></span> <i class="fa fa-caret-right"></i></button>');
|
_ret.push('<span data-tp-select-result></span> <i class="fa fa-caret-right"></i></button>');
|
||||||
|
@ -1317,7 +1322,7 @@ $tp.create_table_filter_role = function (tbl, roles) {
|
||||||
return '所有';
|
return '所有';
|
||||||
if (id_ === 0)
|
if (id_ === 0)
|
||||||
return '尚未设置';
|
return '尚未设置';
|
||||||
for (var i = 0; i < _tblf.roles.length; ++i) {
|
for (let i = 0; i < _tblf.roles.length; ++i) {
|
||||||
if (_tblf.roles[i].id === id_)
|
if (_tblf.roles[i].id === id_)
|
||||||
return _tblf.roles[i].name;
|
return _tblf.roles[i].name;
|
||||||
}
|
}
|
||||||
|
@ -1328,12 +1333,12 @@ $tp.create_table_filter_role = function (tbl, roles) {
|
||||||
_tblf.on_created = function () {
|
_tblf.on_created = function () {
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text('所有');
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text('所有');
|
||||||
$('#' + _tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
$('#' + _tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
||||||
var select = parseInt($(this).attr('data-tp-selector'));
|
let select = parseInt($(this).attr('data-tp-selector'));
|
||||||
if (_tblf.filter_value === select)
|
if (_tblf.filter_value === select)
|
||||||
return;
|
return;
|
||||||
_tblf.filter_value = select;
|
_tblf.filter_value = select;
|
||||||
|
|
||||||
var name = _tblf._id2name(select);
|
let name = _tblf._id2name(select);
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
|
|
||||||
// 刷新数据
|
// 刷新数据
|
||||||
|
@ -1343,7 +1348,7 @@ $tp.create_table_filter_role = function (tbl, roles) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// $tp.create_table_filter_user_state = function (tbl, states, on_created) {
|
// $tp.create_table_filter_user_state = function (tbl, states, on_created) {
|
||||||
// var _tblf = {};
|
// let _tblf = {};
|
||||||
// _tblf._table_ctrl = tbl;
|
// _tblf._table_ctrl = tbl;
|
||||||
// _tblf.dom_id = tbl.dom_id + '-filter-user-state';
|
// _tblf.dom_id = tbl.dom_id + '-filter-user-state';
|
||||||
// _tblf.name = 'user_state';
|
// _tblf.name = 'user_state';
|
||||||
|
@ -1364,13 +1369,13 @@ $tp.create_table_filter_role = function (tbl, roles) {
|
||||||
//
|
//
|
||||||
// _tblf.reset = function (cb_stack) {
|
// _tblf.reset = function (cb_stack) {
|
||||||
// _tblf.filter_value = _tblf.default_value;
|
// _tblf.filter_value = _tblf.default_value;
|
||||||
// var name = _tblf._id2name(_tblf.filter_value);
|
// let name = _tblf._id2name(_tblf.filter_value);
|
||||||
// $('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
// $('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
// cb_stack.exec();
|
// cb_stack.exec();
|
||||||
// };
|
// };
|
||||||
//
|
//
|
||||||
// _tblf.render = function () {
|
// _tblf.render = function () {
|
||||||
// var _ret = [];
|
// let _ret = [];
|
||||||
// _ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select" role="group">');
|
// _ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select" role="group">');
|
||||||
// _ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
// _ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
||||||
// _ret.push('<span data-tp-select-result></span> <i class="fa fa-caret-right"></i></button>');
|
// _ret.push('<span data-tp-select-result></span> <i class="fa fa-caret-right"></i></button>');
|
||||||
|
@ -1388,7 +1393,7 @@ $tp.create_table_filter_role = function (tbl, roles) {
|
||||||
// _tblf._id2name = function (id_) {
|
// _tblf._id2name = function (id_) {
|
||||||
// if (id_ === 0)
|
// if (id_ === 0)
|
||||||
// return '所有';
|
// return '所有';
|
||||||
// for (var i = 0; i < _tblf.states.length; ++i) {
|
// for (let i = 0; i < _tblf.states.length; ++i) {
|
||||||
// if (_tblf.states[i].id === id_)
|
// if (_tblf.states[i].id === id_)
|
||||||
// return _tblf.states[i].name;
|
// return _tblf.states[i].name;
|
||||||
// }
|
// }
|
||||||
|
@ -1399,12 +1404,12 @@ $tp.create_table_filter_role = function (tbl, roles) {
|
||||||
// _tblf.on_created = function () {
|
// _tblf.on_created = function () {
|
||||||
// $('#' + _tblf.dom_id + ' span[data-tp-select-result]').text('所有');
|
// $('#' + _tblf.dom_id + ' span[data-tp-select-result]').text('所有');
|
||||||
// $('#' + _tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
// $('#' + _tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
||||||
// var select = parseInt($(this).attr('data-tp-selector'));
|
// let select = parseInt($(this).attr('data-tp-selector'));
|
||||||
// if (_tblf.filter_value === select)
|
// if (_tblf.filter_value === select)
|
||||||
// return;
|
// return;
|
||||||
// _tblf.filter_value = select;
|
// _tblf.filter_value = select;
|
||||||
//
|
//
|
||||||
// var name = _tblf._id2name(select);
|
// let name = _tblf._id2name(select);
|
||||||
// // console.log(select, name);
|
// // console.log(select, name);
|
||||||
//
|
//
|
||||||
// $('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
// $('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
|
@ -1417,7 +1422,7 @@ $tp.create_table_filter_role = function (tbl, roles) {
|
||||||
// };
|
// };
|
||||||
|
|
||||||
$tp.create_table_header_filter_state = function (tbl, name, states, exclude_ids) {
|
$tp.create_table_header_filter_state = function (tbl, name, states, exclude_ids) {
|
||||||
var _tblf = {};
|
let _tblf = {};
|
||||||
_tblf._table_ctrl = tbl;
|
_tblf._table_ctrl = tbl;
|
||||||
_tblf.dom_id = tbl.dom_id + '-header-filter-' + name;
|
_tblf.dom_id = tbl.dom_id + '-header-filter-' + name;
|
||||||
_tblf.name = name;
|
_tblf.name = name;
|
||||||
|
@ -1426,7 +1431,7 @@ $tp.create_table_header_filter_state = function (tbl, name, states, exclude_ids)
|
||||||
|
|
||||||
_tblf.states = [];
|
_tblf.states = [];
|
||||||
if (exclude_ids && exclude_ids.length > 0) {
|
if (exclude_ids && exclude_ids.length > 0) {
|
||||||
for (var i = 0; i < states.length; ++i) {
|
for (let i = 0; i < states.length; ++i) {
|
||||||
if (_.indexOf(exclude_ids, states[i].id) !== -1)
|
if (_.indexOf(exclude_ids, states[i].id) !== -1)
|
||||||
continue;
|
continue;
|
||||||
_tblf.states.push(states[i]);
|
_tblf.states.push(states[i]);
|
||||||
|
@ -1443,7 +1448,7 @@ $tp.create_table_header_filter_state = function (tbl, name, states, exclude_ids)
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblf.get_filter = function () {
|
_tblf.get_filter = function () {
|
||||||
var ret = {};
|
let ret = {};
|
||||||
if (_tblf.default_value === _tblf.filter_value)
|
if (_tblf.default_value === _tblf.filter_value)
|
||||||
return ret;
|
return ret;
|
||||||
ret[_tblf.name] = _tblf.filter_value;
|
ret[_tblf.name] = _tblf.filter_value;
|
||||||
|
@ -1452,13 +1457,13 @@ $tp.create_table_header_filter_state = function (tbl, name, states, exclude_ids)
|
||||||
|
|
||||||
_tblf.reset = function (cb_stack) {
|
_tblf.reset = function (cb_stack) {
|
||||||
_tblf.filter_value = _tblf.default_value;
|
_tblf.filter_value = _tblf.default_value;
|
||||||
var name = _tblf._id2name(_tblf.filter_value);
|
let name = _tblf._id2name(_tblf.filter_value);
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
cb_stack.exec();
|
cb_stack.exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblf.render = function () {
|
_tblf.render = function () {
|
||||||
var _ret = [];
|
let _ret = [];
|
||||||
_ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select" role="group">');
|
_ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select" role="group">');
|
||||||
_ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
_ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
||||||
_ret.push('<span data-tp-select-result></span> <i class="fa fa-caret-right"></i></button>');
|
_ret.push('<span data-tp-select-result></span> <i class="fa fa-caret-right"></i></button>');
|
||||||
|
@ -1476,7 +1481,7 @@ $tp.create_table_header_filter_state = function (tbl, name, states, exclude_ids)
|
||||||
_tblf._id2name = function (id_) {
|
_tblf._id2name = function (id_) {
|
||||||
if (id_ === 0)
|
if (id_ === 0)
|
||||||
return '所有';
|
return '所有';
|
||||||
for (var i = 0; i < _tblf.states.length; ++i) {
|
for (let i = 0; i < _tblf.states.length; ++i) {
|
||||||
if (_tblf.states[i].id === id_)
|
if (_tblf.states[i].id === id_)
|
||||||
return _tblf.states[i].name;
|
return _tblf.states[i].name;
|
||||||
}
|
}
|
||||||
|
@ -1487,12 +1492,12 @@ $tp.create_table_header_filter_state = function (tbl, name, states, exclude_ids)
|
||||||
_tblf.on_created = function () {
|
_tblf.on_created = function () {
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text('所有');
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text('所有');
|
||||||
$('#' + _tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
$('#' + _tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
||||||
var select = parseInt($(this).attr('data-tp-selector'));
|
let select = parseInt($(this).attr('data-tp-selector'));
|
||||||
if (_tblf.filter_value === select)
|
if (_tblf.filter_value === select)
|
||||||
return;
|
return;
|
||||||
_tblf.filter_value = select;
|
_tblf.filter_value = select;
|
||||||
|
|
||||||
var name = _tblf._id2name(select);
|
let name = _tblf._id2name(select);
|
||||||
|
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
|
|
||||||
|
@ -1503,7 +1508,7 @@ $tp.create_table_header_filter_state = function (tbl, name, states, exclude_ids)
|
||||||
};
|
};
|
||||||
|
|
||||||
$tp.create_table_header_filter_dropdown = function (tbl, name, states, exclude_ids) {
|
$tp.create_table_header_filter_dropdown = function (tbl, name, states, exclude_ids) {
|
||||||
var _tblf = {};
|
let _tblf = {};
|
||||||
_tblf._table_ctrl = tbl;
|
_tblf._table_ctrl = tbl;
|
||||||
_tblf.dom_id = tbl.dom_id + '-header-filter-' + name;
|
_tblf.dom_id = tbl.dom_id + '-header-filter-' + name;
|
||||||
_tblf.name = name;
|
_tblf.name = name;
|
||||||
|
@ -1512,7 +1517,7 @@ $tp.create_table_header_filter_dropdown = function (tbl, name, states, exclude_i
|
||||||
|
|
||||||
_tblf.states = [];
|
_tblf.states = [];
|
||||||
if (exclude_ids && exclude_ids.length > 0) {
|
if (exclude_ids && exclude_ids.length > 0) {
|
||||||
for (var i = 0; i < states.length; ++i) {
|
for (let i = 0; i < states.length; ++i) {
|
||||||
if (_.indexOf(exclude_ids, states[i].id) !== -1)
|
if (_.indexOf(exclude_ids, states[i].id) !== -1)
|
||||||
continue;
|
continue;
|
||||||
_tblf.states.push(states[i]);
|
_tblf.states.push(states[i]);
|
||||||
|
@ -1529,7 +1534,7 @@ $tp.create_table_header_filter_dropdown = function (tbl, name, states, exclude_i
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblf.get_filter = function () {
|
_tblf.get_filter = function () {
|
||||||
var ret = {};
|
let ret = {};
|
||||||
if (_tblf.default_value === _tblf.filter_value)
|
if (_tblf.default_value === _tblf.filter_value)
|
||||||
return ret;
|
return ret;
|
||||||
ret[_tblf.name] = _tblf.filter_value;
|
ret[_tblf.name] = _tblf.filter_value;
|
||||||
|
@ -1538,13 +1543,13 @@ $tp.create_table_header_filter_dropdown = function (tbl, name, states, exclude_i
|
||||||
|
|
||||||
_tblf.reset = function (cb_stack) {
|
_tblf.reset = function (cb_stack) {
|
||||||
_tblf.filter_value = _tblf.default_value;
|
_tblf.filter_value = _tblf.default_value;
|
||||||
var name = _tblf._id2name(_tblf.filter_value);
|
let name = _tblf._id2name(_tblf.filter_value);
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
cb_stack.exec();
|
cb_stack.exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblf.render = function () {
|
_tblf.render = function () {
|
||||||
var _ret = [];
|
let _ret = [];
|
||||||
_ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select" role="group">');
|
_ret.push('<div id="' + _tblf.dom_id + '" class="btn-group search-select" role="group">');
|
||||||
_ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
_ret.push('<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">');
|
||||||
_ret.push('<span data-tp-select-result></span> <i class="fa fa-caret-right"></i></button>');
|
_ret.push('<span data-tp-select-result></span> <i class="fa fa-caret-right"></i></button>');
|
||||||
|
@ -1562,7 +1567,7 @@ $tp.create_table_header_filter_dropdown = function (tbl, name, states, exclude_i
|
||||||
_tblf._id2name = function (id_) {
|
_tblf._id2name = function (id_) {
|
||||||
if (id_ === 0)
|
if (id_ === 0)
|
||||||
return '所有';
|
return '所有';
|
||||||
for (var i = 0; i < _tblf.states.length; ++i) {
|
for (let i = 0; i < _tblf.states.length; ++i) {
|
||||||
if (_tblf.states[i].id === id_)
|
if (_tblf.states[i].id === id_)
|
||||||
return _tblf.states[i].name;
|
return _tblf.states[i].name;
|
||||||
}
|
}
|
||||||
|
@ -1574,12 +1579,12 @@ $tp.create_table_header_filter_dropdown = function (tbl, name, states, exclude_i
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text('所有');
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text('所有');
|
||||||
$('#' + _tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
$('#' + _tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
||||||
|
|
||||||
var select = parseInt($(this).attr('data-tp-selector'));
|
let select = parseInt($(this).attr('data-tp-selector'));
|
||||||
if (_tblf.filter_value === select)
|
if (_tblf.filter_value === select)
|
||||||
return;
|
return;
|
||||||
_tblf.filter_value = select;
|
_tblf.filter_value = select;
|
||||||
|
|
||||||
var name = _tblf._id2name(select);
|
let name = _tblf._id2name(select);
|
||||||
|
|
||||||
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
$('#' + _tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
|
|
||||||
|
@ -1590,7 +1595,7 @@ $tp.create_table_header_filter_dropdown = function (tbl, name, states, exclude_i
|
||||||
};
|
};
|
||||||
|
|
||||||
$tp.create_table_filter_group = function (tbl, name, dom_id, groups) {
|
$tp.create_table_filter_group = function (tbl, name, dom_id, groups) {
|
||||||
var _tblf = {};
|
let _tblf = {};
|
||||||
_tblf._table_ctrl = tbl;
|
_tblf._table_ctrl = tbl;
|
||||||
_tblf.dom_id = dom_id;
|
_tblf.dom_id = dom_id;
|
||||||
_tblf.name = name;
|
_tblf.name = name;
|
||||||
|
@ -1601,7 +1606,7 @@ $tp.create_table_filter_group = function (tbl, name, dom_id, groups) {
|
||||||
_tblf._table_ctrl.add_filter_ctrl(_tblf.name, _tblf);
|
_tblf._table_ctrl.add_filter_ctrl(_tblf.name, _tblf);
|
||||||
|
|
||||||
_tblf.init = function (cb_stack) {
|
_tblf.init = function (cb_stack) {
|
||||||
var html = [];
|
let html = [];
|
||||||
html.push('<li><a href="javascript:;" data-tp-selector="-1" data-name="所有"><i class="fa fa-caret-right fa-fw"></i> 所有</a></li>');
|
html.push('<li><a href="javascript:;" data-tp-selector="-1" data-name="所有"><i class="fa fa-caret-right fa-fw"></i> 所有</a></li>');
|
||||||
$.each(_tblf.groups, function (i, item) {
|
$.each(_tblf.groups, function (i, item) {
|
||||||
html.push('<li><a href="javascript:;" data-tp-selector="' + item.id + '" data-name="' + item.name + '"><i class="fa fa-caret-right fa-fw"></i> ' + item.name + '</a></li>');
|
html.push('<li><a href="javascript:;" data-tp-selector="' + item.id + '" data-name="' + item.name + '"><i class="fa fa-caret-right fa-fw"></i> ' + item.name + '</a></li>');
|
||||||
|
@ -1610,12 +1615,12 @@ $tp.create_table_filter_group = function (tbl, name, dom_id, groups) {
|
||||||
|
|
||||||
|
|
||||||
$(_tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
$(_tblf.dom_id + ' li a[data-tp-selector]').click(function () {
|
||||||
var select = parseInt($(this).attr('data-tp-selector'));
|
let select = parseInt($(this).attr('data-tp-selector'));
|
||||||
if (_tblf.filter_value === select)
|
if (_tblf.filter_value === select)
|
||||||
return;
|
return;
|
||||||
_tblf.filter_value = select;
|
_tblf.filter_value = select;
|
||||||
|
|
||||||
var name = _tblf._id2name(select);
|
let name = _tblf._id2name(select);
|
||||||
$(_tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
$(_tblf.dom_id + ' span[data-tp-select-result]').text(name);
|
||||||
|
|
||||||
// 刷新数据
|
// 刷新数据
|
||||||
|
@ -1627,7 +1632,7 @@ $tp.create_table_filter_group = function (tbl, name, dom_id, groups) {
|
||||||
};
|
};
|
||||||
|
|
||||||
_tblf.get_filter = function () {
|
_tblf.get_filter = function () {
|
||||||
var ret = {};
|
let ret = {};
|
||||||
ret[_tblf.name] = _tblf.filter_value;
|
ret[_tblf.name] = _tblf.filter_value;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
@ -1637,7 +1642,7 @@ $tp.create_table_filter_group = function (tbl, name, dom_id, groups) {
|
||||||
return '所有';
|
return '所有';
|
||||||
// if (id_ === 0)
|
// if (id_ === 0)
|
||||||
// return '尚未设置';
|
// return '尚未设置';
|
||||||
for (var i = 0; i < _tblf.groups.length; ++i) {
|
for (let i = 0; i < _tblf.groups.length; ++i) {
|
||||||
if (_tblf.groups[i].id === id_)
|
if (_tblf.groups[i].id === id_)
|
||||||
return _tblf.groups[i].name;
|
return _tblf.groups[i].name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
<div id="steps-detail" class="steps-detail"></div>
|
<div id="steps-detail" class="steps-detail"></div>
|
||||||
<div><p id="message" class="op_box" style="display:none;"></p></div>
|
<div><p id="message" class="op_box" style="display:none;"></p></div>
|
||||||
|
|
||||||
|
|
||||||
<div id="step2" style="display:none;">
|
<div id="step2" style="display:none;">
|
||||||
<hr/>
|
<hr/>
|
||||||
<h2><i class="fa fa-chevron-right"></i> 已完成!</h2>
|
<h2><i class="fa fa-chevron-right"></i> 已完成!</h2>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block block_body %}
|
{% block block_body %}
|
||||||
<div class="page-content-inner">
|
<div class="page-content-inner">
|
||||||
<div class="box box-nav-tabs">
|
<div class="box box-nav-tabs">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active"><a href="#tab-info" data-toggle="tab">基本信息</a></li>
|
<li class="active"><a href="#tab-info" data-toggle="tab">基本信息</a></li>
|
||||||
|
@ -16,7 +16,8 @@
|
||||||
<li><a href="#tab-session" data-toggle="tab">连接控制</a></li>
|
<li><a href="#tab-session" data-toggle="tab">连接控制</a></li>
|
||||||
<li><a href="#tab-smtp" data-toggle="tab">邮件系统</a></li>
|
<li><a href="#tab-smtp" data-toggle="tab">邮件系统</a></li>
|
||||||
<li><a href="#tab-storage" data-toggle="tab">存储</a></li>
|
<li><a href="#tab-storage" data-toggle="tab">存储</a></li>
|
||||||
{# ## <li><a href="#tab-backup" data-toggle="tab">备份</a></li>#}
|
<li><a href="#tab-integration" data-toggle="tab">密钥管理</a></li>
|
||||||
|
{# ## <li><a href="#tab-backup" data-toggle="tab">备份</a></li>#}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
|
@ -86,24 +87,24 @@
|
||||||
<span class="desc">还可以为每个用户指定特定的登录认证方式。</span>
|
<span class="desc">还可以为每个用户指定特定的登录认证方式。</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{### <tr>#}
|
{### <tr>#}
|
||||||
{### <td class="key"></td>#}
|
{### <td class="key"></td>#}
|
||||||
{### <td class="value">#}
|
{### <td class="value">#}
|
||||||
{### <div id="sec-auth-username-password" class="tp-checkbox tp-editable">用户名 + 密码</div>#}
|
{### <div id="sec-auth-username-password" class="tp-checkbox tp-editable">用户名 + 密码</div>#}
|
||||||
{### </td>#}
|
{### </td>#}
|
||||||
{### </tr>#}
|
{### </tr>#}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="key"></td>
|
<td class="key"></td>
|
||||||
<td class="value">
|
<td class="value">
|
||||||
<div id="sec-auth-username-password-captcha" class="tp-checkbox tp-editable">用户名 + 密码 + 验证码</div>
|
<div id="sec-auth-username-password-captcha" class="tp-checkbox tp-editable">用户名 + 密码 + 验证码</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{### <tr>#}
|
{### <tr>#}
|
||||||
{### <td class="key"></td>#}
|
{### <td class="key"></td>#}
|
||||||
{### <td class="value">#}
|
{### <td class="value">#}
|
||||||
{### <div id="sec-auth-username-oath" class="tp-checkbox tp-editable">用户名 + 身份认证器动态密码</div>#}
|
{### <div id="sec-auth-username-oath" class="tp-checkbox tp-editable">用户名 + 身份认证器动态密码</div>#}
|
||||||
{### </td>#}
|
{### </td>#}
|
||||||
{### </tr>#}
|
{### </tr>#}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="key"></td>
|
<td class="key"></td>
|
||||||
<td class="value">
|
<td class="value">
|
||||||
|
@ -142,31 +143,31 @@
|
||||||
注意:运维授权策略的连接控制选项将继承系统连接控制选项的设定。例如,在本界面设定"不允许SFTP连接",则所有运维授权策略中的SFTP连接均被禁止。又如,在本界面设定"允许SFTP连接",但某个运维授权策略中禁止SFTP连接,则该运维授权策略中的所有SFTP连接均被禁止。
|
注意:运维授权策略的连接控制选项将继承系统连接控制选项的设定。例如,在本界面设定"不允许SFTP连接",则所有运维授权策略中的SFTP连接均被禁止。又如,在本界面设定"允许SFTP连接",但某个运维授权策略中禁止SFTP连接,则该运维授权策略中的所有SFTP连接均被禁止。
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-config-list">
|
<table class="table table-config-list">
|
||||||
{### <tr>#}
|
{### <tr>#}
|
||||||
{### <td colspan="2" class="title">全局会话选项</td>#}
|
{### <td colspan="2" class="title">全局会话选项</td>#}
|
||||||
{### </tr>#}
|
{### </tr>#}
|
||||||
{### <tr>#}
|
{### <tr>#}
|
||||||
{### <td class="key"></td>#}
|
{### <td class="key"></td>#}
|
||||||
{### <td class="value">#}
|
{### <td class="value">#}
|
||||||
{### <div id="sess-record-allow-replay" class="tp-checkbox tp-editable">记录会话历史</div>#}
|
{### <div id="sess-record-allow-replay" class="tp-checkbox tp-editable">记录会话历史</div>#}
|
||||||
{### </td>#}
|
{### </td>#}
|
||||||
{### </tr>#}
|
{### </tr>#}
|
||||||
{### <tr>#}
|
{### <tr>#}
|
||||||
{### <td class="key"></td>#}
|
{### <td class="key"></td>#}
|
||||||
{### <td class="value">#}
|
{### <td class="value">#}
|
||||||
{### <div id="sess-record-allow-real-time" class="tp-checkbox tp-disabled">允许实时监控(开发中)</div>#}
|
{### <div id="sess-record-allow-real-time" class="tp-checkbox tp-disabled">允许实时监控(开发中)</div>#}
|
||||||
{### </td>#}
|
{### </td>#}
|
||||||
{### </tr>#}
|
{### </tr>#}
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="title">
|
<td colspan="2" class="title">
|
||||||
{### <hr class="hr-sm"/>#}
|
{### <hr class="hr-sm"/>#}
|
||||||
全局RDP选项(注:尚未实现)
|
全局RDP选项(注:尚未实现)
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{# ## <div id="rdp-allow-desktop" class="tp-checkbox tp-editable tp-selected">允许 远程桌面</div>#}
|
{# ## <div id="rdp-allow-desktop" class="tp-checkbox tp-editable tp-selected">允许 远程桌面</div>#}
|
||||||
{# ## <div id="rdp-allow-app" class="tp-checkbox">允许 远程应用</div>#}
|
{# ## <div id="rdp-allow-app" class="tp-checkbox">允许 远程应用</div>#}
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="key"></td>
|
<td class="key"></td>
|
||||||
|
@ -194,9 +195,9 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{### <div id="ssh-allow-x11" class="tp-checkbox">允许X11转发</div>#}
|
{### <div id="ssh-allow-x11" class="tp-checkbox">允许X11转发</div>#}
|
||||||
{### <div id="ssh-allow-tunnel" class="tp-checkbox">允许隧道转发</div>#}
|
{### <div id="ssh-allow-tunnel" class="tp-checkbox">允许隧道转发</div>#}
|
||||||
{### <div id="ssh-allow-exec" class="tp-checkbox">允许远程执行exec</div>#}
|
{### <div id="ssh-allow-exec" class="tp-checkbox">允许远程执行exec</div>#}
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="key"></td>
|
<td class="key"></td>
|
||||||
|
@ -210,12 +211,12 @@
|
||||||
<div id="sess-ssh-allow-sftp" class="tp-checkbox tp-editable">允许SFTP</div>
|
<div id="sess-ssh-allow-sftp" class="tp-checkbox tp-editable">允许SFTP</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{### <tr>#}
|
{### <tr>#}
|
||||||
{### <td class="key"></td>#}
|
{### <td class="key"></td>#}
|
||||||
{### <td class="value">#}
|
{### <td class="value">#}
|
||||||
{### <div id="ssh-allow-x11" class="tp-checkbox tp-disabled">允许X11转发(开发中)</div>#}
|
{### <div id="ssh-allow-x11" class="tp-checkbox tp-disabled">允许X11转发(开发中)</div>#}
|
||||||
{### </td>#}
|
{### </td>#}
|
||||||
{### </tr>#}
|
{### </tr>#}
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="title">
|
<td colspan="2" class="title">
|
||||||
|
@ -373,116 +374,142 @@
|
||||||
</table>
|
</table>
|
||||||
<hr/>
|
<hr/>
|
||||||
<button id="btn-save-storage-config" class="btn btn-sm btn-primary"><i class="fa fa-check-circle fa-fw"></i> 保存存储设置</button>
|
<button id="btn-save-storage-config" class="btn btn-sm btn-primary"><i class="fa fa-check-circle fa-fw"></i> 保存存储设置</button>
|
||||||
{# ## <button id="btn-clear-storage" class="btn btn-sm btn-danger"><i class="fa fa-edit fa-fw"></i> 立即清理</button>#}
|
{# ## <button id="btn-clear-storage" class="btn btn-sm btn-danger"><i class="fa fa-edit fa-fw"></i> 立即清理</button>#}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- panel for integration -->
|
||||||
|
<div class="tab-pane" id="tab-integration">
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<span class="table-name"><i class="fa fa-list fa-fw"></i> 密钥列表</span>
|
||||||
|
<button id="btn-refresh-integration" class="btn btn-sm btn-default"><i class="fa fa-redo fa-fw"></i> 刷新列表</button>
|
||||||
|
<button class="btn btn-sm btn-primary" id="btn-add-integration"><i class="fa fa-plus"></i> 添加密钥</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-info">
|
||||||
|
说明:外部服务集成密钥用于第三方服务与Teleport服务集成时,调用Teleport的API接口所需要的access-key和access-secret。
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="table-integration" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell checkbox-select-all"><input id="table-integration-select-all" type="checkbox"/></div>
|
||||||
|
<div class="table-extend-cell group-actions">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button id="btn-remove-integration" type="button" class="btn btn-default"><i class="fas fa-trash-alt fa-fw"></i> 删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- panel for backup config -->
|
<!-- panel for backup config -->
|
||||||
{# ## <div class="tab-pane" id="tab-backup">#}
|
{# ## <div class="tab-pane" id="tab-backup">#}
|
||||||
{# ## <div class="alert alert-danger">备份功能尚未实现</div>#}
|
{# ## <div class="alert alert-danger">备份功能尚未实现</div>#}
|
||||||
{# ###}
|
{# ###}
|
||||||
{# ## <table class="table table-config-list">#}
|
{# ## <table class="table table-config-list">#}
|
||||||
{# ## <tr>#}
|
{# ## <tr>#}
|
||||||
{# ## <td colspan="2" class="title">数据库备份</td>#}
|
{# ## <td colspan="2" class="title">数据库备份</td>#}
|
||||||
{# ## </tr>#}
|
{# ## </tr>#}
|
||||||
{# ## <tr>#}
|
{# ## <tr>#}
|
||||||
{# ## <td class="key">备份范围</td>#}
|
{# ## <td class="key">备份范围</td>#}
|
||||||
{# ## <td class="value">#}
|
{# ## <td class="value">#}
|
||||||
{# ## <div id="btn-bak-syslog" class="tp-checkbox tp-editable">包括系统日志</div>#}
|
{# ## <div id="btn-bak-syslog" class="tp-checkbox tp-editable">包括系统日志</div>#}
|
||||||
{# ## </td>#}
|
{# ## </td>#}
|
||||||
{# ## </tr>#}
|
{# ## </tr>#}
|
||||||
{# ## <tr>#}
|
{# ## <tr>#}
|
||||||
{# ## <td class="key"></td>#}
|
{# ## <td class="key"></td>#}
|
||||||
{# ## <td class="value">#}
|
{# ## <td class="value">#}
|
||||||
{# ## <div id="btn-backup-alert" class="tp-checkbox tp-editable">包括报警日志</div>#}
|
{# ## <div id="btn-backup-alert" class="tp-checkbox tp-editable">包括报警日志</div>#}
|
||||||
{# ## </td>#}
|
{# ## </td>#}
|
||||||
{# ## </tr>#}
|
{# ## </tr>#}
|
||||||
{# ## <tr>#}
|
{# ## <tr>#}
|
||||||
{# ## <td class="key"></td>#}
|
{# ## <td class="key"></td>#}
|
||||||
{# ## <td class="value">#}
|
{# ## <td class="value">#}
|
||||||
{# ## <div id="btn-backup-ops" class="tp-checkbox tp-editable">包括运维记录</div>#}
|
{# ## <div id="btn-backup-ops" class="tp-checkbox tp-editable">包括运维记录</div>#}
|
||||||
{# ## </td>#}
|
{# ## </td>#}
|
||||||
{# ## </tr>#}
|
{# ## </tr>#}
|
||||||
{# ## <tr>#}
|
{# ## <tr>#}
|
||||||
{# ## <td class="key">自动备份</td>#}
|
{# ## <td class="key">自动备份</td>#}
|
||||||
{# ## <td class="value">#}
|
{# ## <td class="value">#}
|
||||||
{# ## <div id="btn-auto-backup" class="tp-checkbox tp-editable tp-selected">在指定时间点自动备份数据库</div>#}
|
{# ## <div id="btn-auto-backup" class="tp-checkbox tp-editable tp-selected">在指定时间点自动备份数据库</div>#}
|
||||||
{# ## </td>#}
|
{# ## </td>#}
|
||||||
{# ## </tr>#}
|
{# ## </tr>#}
|
||||||
{# ## <tr>#}
|
{# ## <tr>#}
|
||||||
{# ## <td class="key">备份时间点</td>#}
|
{# ## <td class="key">备份时间点</td>#}
|
||||||
{# ## <td class="value">#}
|
{# ## <td class="value">#}
|
||||||
{# ## <select id="select-backup-hour">#}
|
{# ## <select id="select-backup-hour">#}
|
||||||
{# ## <option>00</option>#}
|
{# ## <option>00</option>#}
|
||||||
{# ## <option>01</option>#}
|
{# ## <option>01</option>#}
|
||||||
{# ## <option>02</option>#}
|
{# ## <option>02</option>#}
|
||||||
{# ## <option selected="selected">03</option>#}
|
{# ## <option selected="selected">03</option>#}
|
||||||
{# ## <option>04</option>#}
|
{# ## <option>04</option>#}
|
||||||
{# ## <option>05</option>#}
|
{# ## <option>05</option>#}
|
||||||
{# ## <option>06</option>#}
|
{# ## <option>06</option>#}
|
||||||
{# ## <option>07</option>#}
|
{# ## <option>07</option>#}
|
||||||
{# ## <option>08</option>#}
|
{# ## <option>08</option>#}
|
||||||
{# ## <option>09</option>#}
|
{# ## <option>09</option>#}
|
||||||
{# ## <option>10</option>#}
|
{# ## <option>10</option>#}
|
||||||
{# ## <option>11</option>#}
|
{# ## <option>11</option>#}
|
||||||
{# ## <option>12</option>#}
|
{# ## <option>12</option>#}
|
||||||
{# ## <option>13</option>#}
|
{# ## <option>13</option>#}
|
||||||
{# ## <option>14</option>#}
|
{# ## <option>14</option>#}
|
||||||
{# ## <option>15</option>#}
|
{# ## <option>15</option>#}
|
||||||
{# ## <option>16</option>#}
|
{# ## <option>16</option>#}
|
||||||
{# ## <option>17</option>#}
|
{# ## <option>17</option>#}
|
||||||
{# ## <option>18</option>#}
|
{# ## <option>18</option>#}
|
||||||
{# ## <option>19</option>#}
|
{# ## <option>19</option>#}
|
||||||
{# ## <option>20</option>#}
|
{# ## <option>20</option>#}
|
||||||
{# ## <option>21</option>#}
|
{# ## <option>21</option>#}
|
||||||
{# ## <option>22</option>#}
|
{# ## <option>22</option>#}
|
||||||
{# ## <option>23</option>#}
|
{# ## <option>23</option>#}
|
||||||
{# ## </select>#}
|
{# ## </select>#}
|
||||||
{# ## 时#}
|
{# ## 时#}
|
||||||
{# ## <select id="select-backup-min">#}
|
{# ## <select id="select-backup-min">#}
|
||||||
{# ## <option selected="selected">00</option>#}
|
{# ## <option selected="selected">00</option>#}
|
||||||
{# ## <option>05</option>#}
|
{# ## <option>05</option>#}
|
||||||
{# ## <option>10</option>#}
|
{# ## <option>10</option>#}
|
||||||
{# ## <option>15</option>#}
|
{# ## <option>15</option>#}
|
||||||
{# ## <option>20</option>#}
|
{# ## <option>20</option>#}
|
||||||
{# ## <option>25</option>#}
|
{# ## <option>25</option>#}
|
||||||
{# ## <option>30</option>#}
|
{# ## <option>30</option>#}
|
||||||
{# ## <option>35</option>#}
|
{# ## <option>35</option>#}
|
||||||
{# ## <option>40</option>#}
|
{# ## <option>40</option>#}
|
||||||
{# ## <option>45</option>#}
|
{# ## <option>45</option>#}
|
||||||
{# ## <option>50</option>#}
|
{# ## <option>50</option>#}
|
||||||
{# ## <option>55</option>#}
|
{# ## <option>55</option>#}
|
||||||
{# ## </select>#}
|
{# ## </select>#}
|
||||||
{# ## 分#}
|
{# ## 分#}
|
||||||
{# ## <span class="desc">每天在指定时间点备份数据库。</span>#}
|
{# ## <span class="desc">每天在指定时间点备份数据库。</span>#}
|
||||||
{# ## </td>#}
|
{# ## </td>#}
|
||||||
{# ## </tr>#}
|
{# ## </tr>#}
|
||||||
{# ## <tr>#}
|
{# ## <tr>#}
|
||||||
{# ## <td class="key">备份保留时长</td>#}
|
{# ## <td class="key">备份保留时长</td>#}
|
||||||
{# ## <td class="value">#}
|
{# ## <td class="value">#}
|
||||||
{# ## <input id="backup-keep-timeout" type="text" value="7"/><span class="unit">天</span><span class="desc">1~7。超过设定时间的备份将自动删除,默认为7天。</span>#}
|
{# ## <input id="backup-keep-timeout" type="text" value="7"/><span class="unit">天</span><span class="desc">1~7。超过设定时间的备份将自动删除,默认为7天。</span>#}
|
||||||
{# ## </td>#}
|
{# ## </td>#}
|
||||||
{# ## </tr>#}
|
{# ## </tr>#}
|
||||||
{# ## <tr>#}
|
{# ## <tr>#}
|
||||||
{# ## <td class="key"></td>#}
|
{# ## <td class="key"></td>#}
|
||||||
{# ## <td class="value">#}
|
{# ## <td class="value">#}
|
||||||
{# ## <a href="javascript:;"><i class="fa fa-download"></i> 下载自动备份文件</a>#}
|
{# ## <a href="javascript:;"><i class="fa fa-download"></i> 下载自动备份文件</a>#}
|
||||||
{# ## </td>#}
|
{# ## </td>#}
|
||||||
{# ## </tr>#}
|
{# ## </tr>#}
|
||||||
{# ###}
|
{# ###}
|
||||||
{# ## </table>#}
|
{# ## </table>#}
|
||||||
{# ## <hr/>#}
|
{# ## <hr/>#}
|
||||||
{# ## <button id="btn-save-storage-config" class="btn btn-sm btn-primary"><i class="fa fa-edit fa-fw"></i> 保存存储设置</button>#}
|
{# ## <button id="btn-save-storage-config" class="btn btn-sm btn-primary"><i class="fa fa-edit fa-fw"></i> 保存存储设置</button>#}
|
||||||
{# ## <button id="btn-do-backup" class="btn btn-sm btn-success"><i class="fa fa-edit fa-fw"></i> 立即备份</button>#}
|
{# ## <button id="btn-do-backup" class="btn btn-sm btn-success"><i class="fa fa-edit fa-fw"></i> 立即备份</button>#}
|
||||||
{# ## <button id="btn-import-backup" class="btn btn-sm btn-danger"><i class="fa fa-edit fa-fw"></i> 导入备份</button>#}
|
{# ## <button id="btn-import-backup" class="btn btn-sm btn-danger"><i class="fa fa-edit fa-fw"></i> 导入备份</button>#}
|
||||||
{# ## </div>#}
|
{# ## </div>#}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block block_extend_content %}
|
{% block block_extend_content %}
|
||||||
<!-- dialog for edit smtp config -->
|
<!-- dialog for edit smtp config -->
|
||||||
<div class="modal fade" id="dlg-edit-smtp-config">
|
<div class="modal fade" id="dlg-edit-smtp-config" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
@ -559,8 +586,67 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- dialog for add/edit integration -->
|
||||||
|
<div class="modal fade" id="dlg-edit-integration" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times-circle fa-fw"></i></button>
|
||||||
|
<h3 data-field="dlg-title" class="modal-title"></h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<div class="form-horizontal">
|
||||||
|
|
||||||
|
<div class="form-group form-group-sm">
|
||||||
|
<label for="edit-integration-name" class="col-sm-2 control-label require">名称:</label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="edit-integration-name" type="text" class="form-control" placeholder="外部服务名称"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<div class="control-desc">英文字符和数字,最大64字符</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group form-group-sm">
|
||||||
|
<label for="edit-integration-role" class="col-sm-2 control-label require">权限角色:</label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<div id="edit-integration-role" class="btn-group btn-group-sm"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group form-group-sm">
|
||||||
|
<label for="edit-integration-comment" class="col-sm-2 control-label">备注:</label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="edit-integration-comment" type="text" class="form-control" placeholder=""/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group form-group-sm" id="area-integration-regenerate" style="display:none;">
|
||||||
|
<div class="col-sm-2"></div>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<label><input id="chk-integration-regenerate" type="checkbox" value=""> 重新生成 Access Secret</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12" style="text-align:right;">
|
||||||
|
<button type="button" class="btn btn-sm btn-primary" id="btn-edit-integration-save"><i class="fa fa-check fa-fw"></i> 确定</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 取消</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- dialog for show storage cleanup result -->
|
<!-- dialog for show storage cleanup result -->
|
||||||
<div class="modal fade" id="dlg-result">
|
<div class="modal fade" id="dlg-result" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
|
|
|
@ -283,16 +283,11 @@
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div id="edit-user-message" class="alert alert-danger"
|
<div id="edit-user-message" class="alert alert-danger" style="text-align:left;display:none;"></div>
|
||||||
style="text-align:left;display:none;"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<button type="button" class="btn btn-sm btn-primary" id="btn-edit-user-save"><i
|
<button type="button" class="btn btn-sm btn-primary" id="btn-edit-user-save"><i class="fa fa-check fa-fw"></i> 确定</button>
|
||||||
class="fa fa-check fa-fw"></i> 确定
|
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 取消</button>
|
||||||
</button>
|
|
||||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i
|
|
||||||
class="fa fa-times fa-fw"></i> 取消
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -711,9 +706,7 @@
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12" style="text-align:right;">
|
<div class="col-sm-12" style="text-align:right;">
|
||||||
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal">
|
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 关闭</button>
|
||||||
<i class="fa fa-times fa-fw"></i> 关闭
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -172,7 +172,7 @@ class BaseAppConfig(dict):
|
||||||
os.rename(tmp_file, cfg_file)
|
os.rename(tmp_file, cfg_file)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e.__str__())
|
log.e('{}\n'.format(e.__str__()))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _update_kvs(self, section, key, val):
|
def _update_kvs(self, section, key, val):
|
||||||
|
@ -223,7 +223,7 @@ class BaseAppConfig(dict):
|
||||||
try:
|
try:
|
||||||
return int(self['_kvs'][_sec][_key]), True
|
return int(self['_kvs'][_sec][_key]), True
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print(e.__str__())
|
log.e('{}\n'.format(e.__str__()))
|
||||||
return def_value, False
|
return def_value, False
|
||||||
|
|
||||||
def get_bool(self, key, def_value=False):
|
def get_bool(self, key, def_value=False):
|
||||||
|
|
|
@ -33,6 +33,7 @@ class DatabaseInit:
|
||||||
self._create_syslog()
|
self._create_syslog()
|
||||||
self._create_record()
|
self._create_record()
|
||||||
self._create_record_audit()
|
self._create_record_audit()
|
||||||
|
self._create_integration_auth()
|
||||||
self._make_builtin_data(sysadmin, email, password)
|
self._make_builtin_data(sysadmin, email, password)
|
||||||
except:
|
except:
|
||||||
log.e('[db] can not create and initialize database.\n')
|
log.e('[db] can not create and initialize database.\n')
|
||||||
|
@ -825,6 +826,32 @@ class DatabaseInit:
|
||||||
'CREATE TABLE `{}record_audit` ({});'.format(self.db.table_prefix, ','.join(f))
|
'CREATE TABLE `{}record_audit` ({});'.format(self.db.table_prefix, ','.join(f))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _create_integration_auth(self):
|
||||||
|
""" 第三方服务集成认证信息 """
|
||||||
|
f = list()
|
||||||
|
|
||||||
|
# id: 自增主键
|
||||||
|
f.append('`id` integer PRIMARY KEY {}'.format(self.db.auto_increment))
|
||||||
|
# acc_key: 访问KEY
|
||||||
|
f.append('`acc_key` varchar(32) DEFAULT ""')
|
||||||
|
# acc_sec: 访问密钥
|
||||||
|
f.append('`acc_sec` varchar(64) DEFAULT ""')
|
||||||
|
# role_id: 此访问授权对应的角色ID, 关联到role表(也即对应的权限)
|
||||||
|
f.append('`role_id` int(11) DEFAULT 0')
|
||||||
|
# name: 第三方服务名称
|
||||||
|
f.append('`name` varchar(64) DEFAULT ""')
|
||||||
|
# comment: 描述
|
||||||
|
f.append('`comment` varchar(64) DEFAULT ""')
|
||||||
|
# creator_id: 创建者的id,0=系统默认创建
|
||||||
|
f.append('`creator_id` int(11) DEFAULT 0')
|
||||||
|
# create_time: 创建时间 timestamp
|
||||||
|
f.append('`create_time` int(11) DEFAULT 0')
|
||||||
|
|
||||||
|
self._db_exec(
|
||||||
|
'创建第三方服务集成认证信息表...',
|
||||||
|
'CREATE TABLE `{}integration_auth` ({});'.format(self.db.table_prefix, ','.join(f))
|
||||||
|
)
|
||||||
|
|
||||||
def _make_builtin_data(self, sysadmin, email, password):
|
def _make_builtin_data(self, sysadmin, email, password):
|
||||||
_time_now = tp_timestamp_sec()
|
_time_now = tp_timestamp_sec()
|
||||||
|
|
||||||
|
|
|
@ -221,3 +221,64 @@ class DatabaseUpgrade:
|
||||||
' - 创建核心服务器表...',
|
' - 创建核心服务器表...',
|
||||||
'CREATE TABLE `{}core_server` ({});'.format(self.db.table_prefix, ','.join(f))
|
'CREATE TABLE `{}core_server` ({});'.format(self.db.table_prefix, ','.join(f))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _upgrade_to_v8(self):
|
||||||
|
_step = self.step_begin('准备升级到数据库版本 v8...')
|
||||||
|
self.step_end(_step, 0, '')
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 1. 创建缺失的 integration_auth 表
|
||||||
|
_step = self.step_begin(' - 检查 integration_auth 数据表...')
|
||||||
|
ret = self.db.is_table_exists('{}integration_auth'.format(self.db.table_prefix))
|
||||||
|
if ret is None:
|
||||||
|
self.step_end(_step, -1, '无法连接到数据库')
|
||||||
|
return False
|
||||||
|
elif not ret:
|
||||||
|
_step = self.step_begin(' - 创建数据表 integration_auth...')
|
||||||
|
self._v8_integration_auth()
|
||||||
|
self.step_end(_step, 0)
|
||||||
|
|
||||||
|
_step = self.step_begin(' - 更新数据库版本号...')
|
||||||
|
if not self.db.exec('UPDATE `{}config` SET `value`="8" WHERE `name`="db_ver";'.format(self.db.table_prefix)):
|
||||||
|
self.step_end(_step, -1, '无法更新数据库版本号')
|
||||||
|
return False
|
||||||
|
self.step_end(_step, 0)
|
||||||
|
|
||||||
|
_step = self.step_begin('升级到 v8 完成')
|
||||||
|
self.step_end(_step, 0)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except:
|
||||||
|
log.e('failed.\n')
|
||||||
|
self.step_end(_step, -1)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _v8_integration_auth(self):
|
||||||
|
""" 第三方服务集成认证信息
|
||||||
|
v8 新增
|
||||||
|
"""
|
||||||
|
|
||||||
|
f = list()
|
||||||
|
|
||||||
|
# id: 自增主键
|
||||||
|
f.append('`id` integer PRIMARY KEY {}'.format(self.db.auto_increment))
|
||||||
|
# acc_key: 访问KEY
|
||||||
|
f.append('`acc_key` varchar(32) DEFAULT ""')
|
||||||
|
# acc_sec: 访问密钥
|
||||||
|
f.append('`acc_sec` varchar(64) DEFAULT ""')
|
||||||
|
# role_id: 此访问授权对应的角色ID, 关联到role表(也即对应的权限)
|
||||||
|
f.append('`role_id` int(11) DEFAULT 0')
|
||||||
|
# name: 第三方服务名称
|
||||||
|
f.append('`name` varchar(64) DEFAULT ""')
|
||||||
|
# comment: 描述
|
||||||
|
f.append('`comment` varchar(64) DEFAULT ""')
|
||||||
|
# creator_id: 创建者的id,0=系统默认创建
|
||||||
|
f.append('`creator_id` int(11) DEFAULT 0')
|
||||||
|
# create_time: 创建时间 timestamp
|
||||||
|
f.append('`create_time` int(11) DEFAULT 0')
|
||||||
|
|
||||||
|
self._db_exec(
|
||||||
|
' - 创建第三方服务集成认证信息表...',
|
||||||
|
'CREATE TABLE `{}integration_auth` ({});'.format(self.db.table_prefix, ','.join(f))
|
||||||
|
)
|
||||||
|
|
|
@ -25,7 +25,8 @@ __all__ = ['get_db', 'SQL']
|
||||||
class TPDatabase:
|
class TPDatabase:
|
||||||
# 注意,每次调整数据库结构,必须增加版本号,并且在升级接口中编写对应的升级操作
|
# 注意,每次调整数据库结构,必须增加版本号,并且在升级接口中编写对应的升级操作
|
||||||
# 20190123: server-v3.2.2, db-v7
|
# 20190123: server-v3.2.2, db-v7
|
||||||
DB_VERSION = 7
|
# 20220526: server-v3.6.3, db-v8
|
||||||
|
DB_VERSION = 8
|
||||||
|
|
||||||
DB_TYPE_UNKNOWN = 0
|
DB_TYPE_UNKNOWN = 0
|
||||||
DB_TYPE_SQLITE = 1
|
DB_TYPE_SQLITE = 1
|
||||||
|
|
|
@ -267,6 +267,12 @@ controllers = [
|
||||||
(r'/system/do-ldap-import', system.DoLdapImportHandler),
|
(r'/system/do-ldap-import', system.DoLdapImportHandler),
|
||||||
# - [text] 导出数据库
|
# - [text] 导出数据库
|
||||||
(r'/system/export-db', system.DoExportDBHandler),
|
(r'/system/export-db', system.DoExportDBHandler),
|
||||||
|
# - [json] 获取第三方服务集成使用的密钥列表
|
||||||
|
(r'/system/get-integration', system.DoGetIntegrationHandler),
|
||||||
|
# - [json] 创建/更新第三方服务集成使用的密钥
|
||||||
|
(r'/system/update-integration', system.DoUpdateIntegrationHandler),
|
||||||
|
# - [json] 移除第三方服务集成使用的密钥
|
||||||
|
(r'/system/remove-integration', system.DoRemoveIntegrationHandler),
|
||||||
|
|
||||||
#
|
#
|
||||||
# - [json] 获取服务器时间
|
# - [json] 获取服务器时间
|
||||||
|
|
|
@ -23,7 +23,7 @@ from app.model import user
|
||||||
from app.base.core_server import core_service_async_post_http
|
from app.base.core_server import core_service_async_post_http
|
||||||
from app.base.session import tp_session
|
from app.base.session import tp_session
|
||||||
from app.logic.auth.ldap import Ldap
|
from app.logic.auth.ldap import Ldap
|
||||||
from app.base.utils import tp_timestamp_sec
|
from app.base.utils import tp_timestamp_sec, tp_gen_password
|
||||||
from ._sidebar_menu import tp_generate_sidebar
|
from ._sidebar_menu import tp_generate_sidebar
|
||||||
|
|
||||||
|
|
||||||
|
@ -679,7 +679,6 @@ class DoLdapImportHandler(TPBaseJsonHandler):
|
||||||
|
|
||||||
user_list.append(u)
|
user_list.append(u)
|
||||||
|
|
||||||
print(user_list)
|
|
||||||
user.create_users(self, user_list, success, failed)
|
user.create_users(self, user_list, success, failed)
|
||||||
|
|
||||||
# 对于创建成功的用户,发送密码邮件函
|
# 对于创建成功的用户,发送密码邮件函
|
||||||
|
@ -770,3 +769,83 @@ class DoRebuildAuditAuzMapHandler(TPBaseJsonHandler):
|
||||||
|
|
||||||
err = ops.build_auz_map()
|
err = ops.build_auz_map()
|
||||||
self.write_json(err)
|
self.write_json(err)
|
||||||
|
|
||||||
|
|
||||||
|
class DoGetIntegrationHandler(TPBaseJsonHandler):
|
||||||
|
@tornado.gen.coroutine
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_SYS_CONFIG)
|
||||||
|
if ret != TPE_OK:
|
||||||
|
return
|
||||||
|
|
||||||
|
err, total_count, page_index, row_data = system_model.get_integration(with_acc_sec=False)
|
||||||
|
ret = dict()
|
||||||
|
ret['page_index'] = page_index
|
||||||
|
ret['total'] = total_count
|
||||||
|
ret['data'] = row_data
|
||||||
|
self.write_json(err, data=ret)
|
||||||
|
|
||||||
|
|
||||||
|
class DoUpdateIntegrationHandler(TPBaseJsonHandler):
|
||||||
|
@tornado.gen.coroutine
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_SYS_CONFIG)
|
||||||
|
if ret != TPE_OK:
|
||||||
|
return
|
||||||
|
|
||||||
|
args = self.get_argument('args', None)
|
||||||
|
if args is None:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
try:
|
||||||
|
args = json.loads(args)
|
||||||
|
except:
|
||||||
|
return self.write_json(TPE_JSON_FORMAT)
|
||||||
|
|
||||||
|
try:
|
||||||
|
_id = int(args['id'])
|
||||||
|
_role_id = int(args['role_id'])
|
||||||
|
_name = args['name']
|
||||||
|
_comment = args['comment']
|
||||||
|
if _id != -1:
|
||||||
|
_acc_key = args['acc_key']
|
||||||
|
_regenerate = args['regenerate']
|
||||||
|
except:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
ret = dict()
|
||||||
|
if _id == -1:
|
||||||
|
err, acc_key, acc_sec = system_model.create_integration(self, _role_id, _name, _comment)
|
||||||
|
else:
|
||||||
|
err, acc_key, acc_sec = system_model.update_integration(self, _id, _role_id, _name, _comment, _acc_key, _regenerate)
|
||||||
|
|
||||||
|
if err == TPE_OK:
|
||||||
|
ret['acc_key'] = acc_key
|
||||||
|
ret['acc_sec'] = acc_sec
|
||||||
|
self.write_json(TPE_OK, data=ret)
|
||||||
|
else:
|
||||||
|
self.write_json(err)
|
||||||
|
|
||||||
|
|
||||||
|
class DoRemoveIntegrationHandler(TPBaseJsonHandler):
|
||||||
|
@tornado.gen.coroutine
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_SYS_CONFIG)
|
||||||
|
if ret != TPE_OK:
|
||||||
|
return
|
||||||
|
|
||||||
|
args = self.get_argument('args', None)
|
||||||
|
if args is None:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
try:
|
||||||
|
args = json.loads(args)
|
||||||
|
except:
|
||||||
|
return self.write_json(TPE_JSON_FORMAT)
|
||||||
|
|
||||||
|
try:
|
||||||
|
items = args['items']
|
||||||
|
except:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
err = system_model.remove_integration(self, items)
|
||||||
|
|
||||||
|
self.write_json(err)
|
||||||
|
|
|
@ -13,7 +13,7 @@ from app.const import *
|
||||||
|
|
||||||
class DashboardHandler(tornado.websocket.WebSocketHandler):
|
class DashboardHandler(tornado.websocket.WebSocketHandler):
|
||||||
def check_origin(self, origin): # 针对websocket处理类重写同源检查的方法
|
def check_origin(self, origin): # 针对websocket处理类重写同源检查的方法
|
||||||
print('ws-dashboard origin:', origin)
|
# print('ws-dashboard origin:', origin)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# 接受websocket链接,保存链接实例
|
# 接受websocket链接,保存链接实例
|
||||||
|
|
|
@ -4,7 +4,7 @@ import json
|
||||||
from app.const import *
|
from app.const import *
|
||||||
from app.base.db import get_db, SQL
|
from app.base.db import get_db, SQL
|
||||||
from app.base.logger import log
|
from app.base.logger import log
|
||||||
from app.base.utils import tp_timestamp_sec
|
from app.base.utils import tp_timestamp_sec, tp_gen_password
|
||||||
from . import syslog
|
from . import syslog
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,13 +52,12 @@ def add_role(handler, role_name, privilege):
|
||||||
_id = db.last_insert_id()
|
_id = db.last_insert_id()
|
||||||
|
|
||||||
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "创建角色:{}".format(role_name))
|
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "创建角色:{}".format(role_name))
|
||||||
|
|
||||||
return TPE_OK, _id
|
return TPE_OK, _id
|
||||||
|
|
||||||
|
|
||||||
def update_role(handler, role_id, role_name, privilege):
|
def update_role(handler, role_id, role_name, privilege):
|
||||||
"""
|
"""
|
||||||
更新一个远程账号
|
更新角色
|
||||||
"""
|
"""
|
||||||
db = get_db()
|
db = get_db()
|
||||||
|
|
||||||
|
@ -75,6 +74,8 @@ def update_role(handler, role_id, role_name, privilege):
|
||||||
if not db_ret:
|
if not db_ret:
|
||||||
return TPE_DATABASE
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
operator = handler.get_current_user()
|
||||||
|
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "更新角色:{}".format(role_name))
|
||||||
return TPE_OK
|
return TPE_OK
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,3 +109,105 @@ def remove_role(handler, role_id):
|
||||||
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除角色:{}".format(role_name))
|
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除角色:{}".format(role_name))
|
||||||
|
|
||||||
return TPE_OK
|
return TPE_OK
|
||||||
|
|
||||||
|
|
||||||
|
def get_integration(with_acc_sec=False):
|
||||||
|
s = SQL(get_db())
|
||||||
|
fields = ['id', 'acc_key', 'name', 'comment']
|
||||||
|
if with_acc_sec:
|
||||||
|
fields.append('acc_sec')
|
||||||
|
s.select_from('integration_auth', fields, alt_name='ia')
|
||||||
|
s.left_join('role', ['id', 'name', 'privilege'], join_on='r.id=ia.role_id', alt_name='r', out_map={'id': 'role_id', 'name': 'role_name'})
|
||||||
|
s.order_by('ia.name', True)
|
||||||
|
|
||||||
|
err = s.query()
|
||||||
|
return err, s.total_count, s.page_index, s.recorder
|
||||||
|
|
||||||
|
|
||||||
|
def create_integration(handler, role_id, name, comment):
|
||||||
|
db = get_db()
|
||||||
|
_time_now = tp_timestamp_sec()
|
||||||
|
operator = handler.get_current_user()
|
||||||
|
|
||||||
|
# 1. 随机生成一个access-key并判断是否已经存在了
|
||||||
|
acc_key = ''
|
||||||
|
acc_sec = tp_gen_password(32)
|
||||||
|
for i in range(20):
|
||||||
|
_acc_key = 'TP{}'.format(tp_gen_password(14))
|
||||||
|
sql = 'SELECT `id` FROM {dbtp}integration_auth WHERE `acc_key`="{acc_key}";'.format(dbtp=db.table_prefix, acc_key=_acc_key)
|
||||||
|
db_ret = db.query(sql)
|
||||||
|
if db_ret is not None and len(db_ret) > 0:
|
||||||
|
continue
|
||||||
|
acc_key = _acc_key
|
||||||
|
break
|
||||||
|
if len(acc_key) == 0:
|
||||||
|
return TPE_FAILED, None, None
|
||||||
|
|
||||||
|
sql = 'INSERT INTO `{dbtp}integration_auth` (`acc_key`, `acc_sec`, `role_id`, `name`, `comment`, `creator_id`, `create_time`) VALUES ' \
|
||||||
|
'("{acc_key}", "{acc_sec}", {role_id}, "{name}", "{comment}", {creator_id}, {create_time});' \
|
||||||
|
''.format(dbtp=db.table_prefix, acc_key=acc_key, acc_sec=acc_sec, role_id=role_id, name=name, comment=comment, creator_id=operator['id'], create_time=_time_now)
|
||||||
|
db_ret = db.exec(sql)
|
||||||
|
if not db_ret:
|
||||||
|
return TPE_DATABASE, None, None
|
||||||
|
|
||||||
|
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "创建外部密钥 {}".format(name))
|
||||||
|
return TPE_OK, acc_key, acc_sec
|
||||||
|
|
||||||
|
|
||||||
|
def update_integration(handler, _id, role_id, name, comment, acc_key, regenerate):
|
||||||
|
db = get_db()
|
||||||
|
_time_now = tp_timestamp_sec()
|
||||||
|
operator = handler.get_current_user()
|
||||||
|
|
||||||
|
acc_sec = None
|
||||||
|
|
||||||
|
# 1. 检查 id, access-key 是否存在
|
||||||
|
sql = 'SELECT `id` FROM {dbtp}integration_auth WHERE `id`={ph} AND `acc_key`={ph};'.format(dbtp=db.table_prefix, ph=db.place_holder)
|
||||||
|
db_ret = db.query(sql, (_id, acc_key))
|
||||||
|
if db_ret is None or len(db_ret) == 0:
|
||||||
|
return TPE_NOT_EXISTS, None, None
|
||||||
|
|
||||||
|
if regenerate:
|
||||||
|
acc_sec = tp_gen_password(32)
|
||||||
|
sql = 'UPDATE `{dbtp}integration_auth` SET `name`={ph}, `comment`={ph}, `role_id`={ph}, `acc_sec`={ph} WHERE `id`={ph};' \
|
||||||
|
''.format(dbtp=db.table_prefix, ph=db.place_holder)
|
||||||
|
db_ret = db.exec(sql, (name, comment, role_id, acc_sec, _id,))
|
||||||
|
else:
|
||||||
|
sql = 'UPDATE `{dbtp}integration_auth` SET `name`={ph}, `comment`={ph}, `role_id`={ph} WHERE `id`={ph};' \
|
||||||
|
''.format(dbtp=db.table_prefix, ph=db.place_holder)
|
||||||
|
db_ret = db.exec(sql, (name, comment, role_id, _id,))
|
||||||
|
|
||||||
|
if not db_ret:
|
||||||
|
return TPE_DATABASE, None, None
|
||||||
|
|
||||||
|
syslog.sys_log(operator, handler.request.remote_ip, TPE_OK, "更新外部密钥 {}{}".format(name, ',重新生成access-secret。' if regenerate else ''))
|
||||||
|
return TPE_OK, acc_key, acc_sec
|
||||||
|
|
||||||
|
|
||||||
|
def remove_integration(handler, items):
|
||||||
|
item_ids = ','.join([str(i) for i in items])
|
||||||
|
|
||||||
|
# 1. 获取名称,用于记录系统日志
|
||||||
|
where = 'i.id IN ({ids})'.format(ids=item_ids)
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
s = SQL(db)
|
||||||
|
err = s.select_from('integration_auth', ['name'], alt_name='i').where(where).query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
if len(s.recorder) == 0:
|
||||||
|
return TPE_NOT_EXISTS
|
||||||
|
|
||||||
|
name_list = [n['name'] for n in s.recorder]
|
||||||
|
|
||||||
|
# 删除
|
||||||
|
sql = 'DELETE FROM `{tp}integration_auth` WHERE `id` IN ({ids});'.format(tp=db.table_prefix, ids=item_ids)
|
||||||
|
db_ret = db.exec(sql)
|
||||||
|
if not db_ret:
|
||||||
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
# 记录系统日志
|
||||||
|
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除外部集成密钥:{names}".format(names=','.join(name_list)))
|
||||||
|
|
||||||
|
return TPE_OK
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue