mirror of https://github.com/jumpserver/jumpserver
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1586 lines
49 KiB
1586 lines
49 KiB
//jumpserver 自定义js 2015-01-29 |
|
|
|
//此函数用于checkbox的全选和反选 |
|
var checked = false; |
|
|
|
function check_all(form) { |
|
var checkboxes = document.getElementById(form); |
|
if (checked === false) { |
|
checked = true; |
|
} else { |
|
checked = false; |
|
} |
|
for (var i = 0; i < checkboxes.elements.length; i++) { |
|
if (checkboxes.elements[i].type == "checkbox") { |
|
checkboxes.elements[i].checked = checked; |
|
} |
|
} |
|
} |
|
|
|
function checkAll(id, name) { |
|
var checklist = document.getElementsByName(name); |
|
if (document.getElementById(id).checked) { |
|
for (var i = 0; i < checklist.length; i++) { |
|
checklist[i].checked = 1; |
|
} |
|
} else { |
|
for (var j = 0; j < checklist.length; j++) { |
|
checklist[j].checked = 0; |
|
} |
|
} |
|
} |
|
|
|
//提取指定行的数据,JSON格式 |
|
function GetRowData(row) { |
|
var rowData = {}; |
|
for (var j = 0; j < row.cells.length; j++) { |
|
name = row.parentNode.rows[0].cells[j].getAttribute("Name"); |
|
if (name) { |
|
var value = row.cells[j].getAttribute("Value"); |
|
if (!value) { |
|
value = row.cells[j].innerHTML; |
|
} |
|
rowData[name] = value; |
|
} |
|
} |
|
return rowData; |
|
} |
|
|
|
//此函数用于在多选提交时至少要选择一行 |
|
function GetTableDataBox() { |
|
var tabProduct = document.getElementById("editable"); |
|
var tableData = []; |
|
var returnData = []; |
|
var checkboxes = document.getElementById("contents_form"); |
|
var id_list = []; |
|
len = checkboxes.elements.length; |
|
for (var i = 0; i < len; i++) { |
|
if (checkboxes.elements[i].type == "checkbox" && checkboxes.elements[i].checked === true && checkboxes.elements[i].value != "checkall") { |
|
id_list.push(i); |
|
} |
|
} |
|
for (i in id_list) { |
|
tableData.push(GetRowData(tabProduct.rows[id_list[i]])); |
|
} |
|
|
|
if (id_list.length === 0) { |
|
alert('请至少选择一行!'); |
|
} |
|
returnData.push(tableData); |
|
returnData.push(id_list.length); |
|
return returnData; |
|
} |
|
|
|
function move(from, to, from_o, to_o) { |
|
$("#" + from + " option").each(function () { |
|
if ($(this).prop("selected") === true) { |
|
$("#" + to).append(this); |
|
if (typeof from_o !== 'undefined') { |
|
$("#" + to_o).append($("#" + from_o + " option[value='" + this.value + "']")); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
function move_left(from, to, from_o, to_o) { |
|
$("#" + from + " option").each(function () { |
|
if ($(this).prop("selected") === true) { |
|
$("#" + to).append(this); |
|
if (typeof from_o !== 'undefined') { |
|
$("#" + to_o).append($("#" + from_o + " option[value='" + this.value + "']")); |
|
} |
|
} |
|
$(this).attr("selected", 'true'); |
|
}); |
|
} |
|
|
|
|
|
function selectAll() { |
|
// Select all check box |
|
$('option').each(function () { |
|
$(this).attr('selected', true); |
|
}); |
|
} |
|
|
|
|
|
function getCookie(name) { |
|
var cookieValue = null; |
|
if (document.cookie && document.cookie !== '') { |
|
var cookies = document.cookie.split(';'); |
|
for (var i = 0; i < cookies.length; i++) { |
|
var cookie = jQuery.trim(cookies[i]); |
|
// Does this cookie string begin with the name we want? |
|
if (cookie.substring(0, name.length + 1) === (name + '=')) { |
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); |
|
// break; |
|
} |
|
} |
|
} |
|
return cookieValue; |
|
} |
|
|
|
function csrfSafeMethod(method) { |
|
// these HTTP methods do not require CSRF protection |
|
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); |
|
} |
|
|
|
function setAjaxCSRFToken() { |
|
let prefix = getCookie('SESSION_COOKIE_NAME_PREFIX'); |
|
if (!prefix || [`""`, `''`].indexOf(prefix) > -1) { prefix = ''; } |
|
var csrftoken = getCookie(`${prefix}csrftoken`); |
|
var sessionid = getCookie(`${prefix}sessionid`); |
|
|
|
$.ajaxSetup({ |
|
beforeSend: function (xhr, settings) { |
|
if (!csrfSafeMethod(settings.type) && !this.crossDomain) { |
|
xhr.setRequestHeader("X-CSRFToken", csrftoken); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
function activeNav(prefix) { |
|
if (!prefix) { |
|
prefix = '/core' |
|
} |
|
var path = document.location.pathname; |
|
path = path.replace(prefix, ''); |
|
var urlArray = path.split("/"); |
|
var app = urlArray[1]; |
|
var resource = urlArray[2]; |
|
if (app === '') { |
|
$('#index').addClass('active'); |
|
} else if (app === 'xpack' && resource === 'cloud') { |
|
var item = urlArray[3]; |
|
$("#" + app).addClass('active'); |
|
$('#' + app + ' #' + resource).addClass('active'); |
|
$('#' + app + ' #' + resource + ' #' + item + ' a').css('color', '#ffffff'); |
|
} else if (app === 'settings') { |
|
$("#" + app).addClass('active'); |
|
} else { |
|
$("#" + app).addClass('active'); |
|
$('#' + app + ' #' + resource).addClass('active'); |
|
$('#' + app + ' #' + resource.replace(/-/g, '_')).addClass('active'); |
|
} |
|
} |
|
|
|
function formSubmit(props) { |
|
/* |
|
{ |
|
"form": $("form"), |
|
"data": {}, |
|
"url": "", |
|
"method": "POST", |
|
"redirect_to": "", |
|
"success": function(data, textStatue, jqXHR){}, |
|
"error": function(jqXHR, textStatus, errorThrown) {}, |
|
"message": "", |
|
} |
|
*/ |
|
props = props || {}; |
|
var data = props.data || props.form.serializeObject(); |
|
var redirectTo = props.redirect_to || props.redirectTo; |
|
$.ajax({ |
|
url: props.url, |
|
type: props.method || 'POST', |
|
data: JSON.stringify(data), |
|
contentType: props.content_type || "application/json; charset=utf-8", |
|
dataType: props.data_type || "json" |
|
}).done(function (data, textState, jqXHR) { |
|
if (redirectTo) { |
|
location.href = redirectTo; |
|
} else if (typeof props.success === 'function') { |
|
return props.success(data, textState, jqXHR); |
|
} |
|
}).fail(function (jqXHR, textStatus, errorThrown) { |
|
if (typeof props.error === 'function') { |
|
return props.error(jqXHR, textStatus, errorThrown) |
|
} |
|
if (!props.form) { |
|
alert(jqXHR.responseText); |
|
return |
|
} |
|
if (jqXHR.status === 400) { |
|
var errors = jqXHR.responseJSON; |
|
var noneFieldErrorRef = props.form.children('.alert-danger'); |
|
if (noneFieldErrorRef.length !== 1) { |
|
props.form.prepend('<div class="alert alert-danger has-error" style="display: none"></div>'); |
|
noneFieldErrorRef = props.form.children('.alert-danger'); |
|
} |
|
var noneFieldErrorMsg = ""; |
|
noneFieldErrorRef.css("display", "none"); |
|
noneFieldErrorRef.html(""); |
|
props.form.find(".help-block.error").html(""); |
|
props.form.find(".form-group.has-error").removeClass("has-error"); |
|
|
|
if (typeof errors !== "object") { |
|
noneFieldErrorMsg = errors; |
|
if (noneFieldErrorRef.length === 1) { |
|
noneFieldErrorRef.css('display', 'block'); |
|
noneFieldErrorRef.html(noneFieldErrorMsg); |
|
} |
|
return |
|
} |
|
$.each(errors, function (k, v) { |
|
var fieldRef = props.form.find('[name="' + k + '"]'); |
|
var formGroupRef = fieldRef.parents('.form-group'); |
|
var parentRef = fieldRef.parent(); |
|
var helpBlockRef = parentRef.children('.help-block.error'); |
|
if (helpBlockRef.length === 0) { |
|
parentRef.append('<div class="help-block error"></div>'); |
|
helpBlockRef = parentRef.children('.help-block.error'); |
|
} |
|
if (fieldRef.length === 1 && formGroupRef.length === 1) { |
|
formGroupRef.addClass('has-error'); |
|
var help_msg = v.join("<br/>"); |
|
helpBlockRef.html(help_msg); |
|
} else { |
|
$.each(v, function (kk, vv) { |
|
if (typeof vv === "object") { |
|
$.each(vv, function (kkk, vvv) { |
|
noneFieldErrorMsg += " " + vvv + '<br/>'; |
|
}) |
|
} else { |
|
noneFieldErrorMsg += vv + '<br/>'; |
|
} |
|
}) |
|
} |
|
}); |
|
if (noneFieldErrorRef.length === 1 && noneFieldErrorMsg !== '') { |
|
noneFieldErrorRef.css('display', 'block'); |
|
noneFieldErrorRef.html(noneFieldErrorMsg); |
|
} |
|
$('.has-error :visible').get(0).scrollIntoView(); |
|
} |
|
}) |
|
} |
|
|
|
function requestApi(props) { |
|
// props = {url: .., body: , success: , error: , method: ,} |
|
props = props || {}; |
|
var user_success_message = props.success_message; |
|
var default_success_message = gettext('Update is successful!'); |
|
var user_fail_message = props.fail_message; |
|
var default_failed_message = gettext('An unknown error occurred while updating..'); |
|
var flash_message = props.flash_message || true; |
|
if (props.flash_message === false) { |
|
flash_message = false; |
|
} |
|
var dataBody = props.body || props.data; |
|
if (typeof(dataBody) === "object") { |
|
dataBody = JSON.stringify(dataBody) |
|
} |
|
var headers = props.headers || {} |
|
|
|
$.ajax({ |
|
url: props.url, |
|
type: props.method || "PATCH", |
|
headers: headers, |
|
data: dataBody, |
|
contentType: props.content_type || "application/json; charset=utf-8", |
|
dataType: props.data_type || "json" |
|
}).done(function (data, textStatue, jqXHR) { |
|
if (flash_message) { |
|
var msg = ""; |
|
if (user_success_message) { |
|
msg = user_success_message; |
|
} else { |
|
msg = default_success_message; |
|
} |
|
toastr.success(msg); |
|
} |
|
if (typeof props.success === 'function') { |
|
return props.success(data); |
|
} |
|
}).fail(function (jqXHR, textStatus, errorThrown) { |
|
if (flash_message) { |
|
var msg = ""; |
|
if (user_fail_message) { |
|
msg = user_fail_message; |
|
} else if (jqXHR.responseJSON) { |
|
if (jqXHR.responseJSON.error) { |
|
msg = jqXHR.responseJSON.error |
|
} else if (jqXHR.responseJSON.msg) { |
|
msg = jqXHR.responseJSON.msg |
|
} else if (jqXHR.responseJSON.detail) { |
|
msg = jqXHR.responseJSON.detail |
|
} |
|
} |
|
if (msg === "") { |
|
msg = default_failed_message; |
|
} |
|
toastr.error(msg); |
|
} |
|
if (typeof props.error === 'function') { |
|
return props.error(jqXHR.responseText, jqXHR.responseJSON, jqXHR.status); |
|
} |
|
}); |
|
// return true; |
|
} |
|
|
|
// Sweet Alert for Delete |
|
function objectDelete(obj, name, url, redirectTo, title, success_message) { |
|
function doDelete() { |
|
var body = {}; |
|
var success = function () { |
|
if (!redirectTo) { |
|
$(obj).parent().parent().remove(); |
|
} else { |
|
window.location.href = redirectTo; |
|
} |
|
}; |
|
var fail = function (responseText, responseJSON, status) { |
|
var errorMsg = ''; |
|
if (responseJSON && responseJSON.error) { |
|
errorMsg = ''; |
|
} else if (status === 404) { |
|
errorMsg = gettext("Not found") |
|
} else { |
|
errorMsg = gettext("Server error") |
|
} |
|
swal(gettext('Error'), "[ " + name + " ] " + errorMsg); |
|
}; |
|
requestApi({ |
|
url: url, |
|
body: JSON.stringify(body), |
|
method: 'DELETE', |
|
success_message: success_message || gettext("Delete the success"), |
|
success: success, |
|
error: fail |
|
}); |
|
} |
|
|
|
swal({ |
|
title: title || gettext('Are you sure about deleting it?'), |
|
text: " [" + name + "] ", |
|
type: "warning", |
|
showCancelButton: true, |
|
cancelButtonText: gettext('Cancel'), |
|
confirmButtonColor: "#ed5565", |
|
confirmButtonText: gettext('Confirm'), |
|
closeOnConfirm: true, |
|
}, function () { |
|
doDelete() |
|
}); |
|
} |
|
|
|
function orgDelete(obj, name, url, redirectTo) { |
|
function doDelete() { |
|
var body = {}; |
|
var success = function () { |
|
if (!redirectTo) { |
|
$(obj).parent().parent().remove(); |
|
} else { |
|
window.location.href = redirectTo; |
|
} |
|
}; |
|
var fail = function (responseText, status) { |
|
if (status === 400) { |
|
swal(gettext("Error"), "[ " + name + " ] " + gettext("The organization contains undeleted information. Please try again after deleting"), "error"); |
|
} else if (status === 405) { |
|
swal(gettext("Error"), " [ " + name + " ] " + gettext("Do not perform this operation under this organization. Try again after switching to another organization"), "error"); |
|
} |
|
}; |
|
requestApi({ |
|
url: url, |
|
body: JSON.stringify(body), |
|
method: 'DELETE', |
|
success_message: gettext("Delete the success"), |
|
success: success, |
|
error: fail |
|
}); |
|
} |
|
|
|
swal({ |
|
title: gettext("Please ensure that the following information in the organization has been deleted"), |
|
text: gettext("User list、User group、Asset list、Domain list、Admin user、System user、Labels、Asset permission"), |
|
type: "warning", |
|
showCancelButton: true, |
|
cancelButtonText: gettext('Cancel'), |
|
confirmButtonColor: "#ed5565", |
|
confirmButtonText: gettext('Confirm'), |
|
closeOnConfirm: true |
|
}, function () { |
|
doDelete(); |
|
}); |
|
} |
|
|
|
$.fn.serializeObject = function () { |
|
var o = {}; |
|
var a = this.serializeArray(); |
|
$.each(a, function () { |
|
if (o[this.name] !== undefined) { |
|
if (!o[this.name].push) { |
|
o[this.name] = [o[this.name]]; |
|
} |
|
o[this.name].push(this.value || ''); |
|
} else { |
|
o[this.name] = this.value || ''; |
|
} |
|
}); |
|
return o; |
|
}; |
|
|
|
function makeLabel(data) { |
|
return "<label class='detail-key'><b>" + data[0] + ": </b></label> " + data[1] + "</br>" |
|
} |
|
|
|
function parseTableFilter(value) { |
|
var cleanValues = []; |
|
if (!value) { |
|
return {} |
|
} |
|
var valuesArray = value.split(':'); |
|
for (var i=0; i<valuesArray.length; i++) { |
|
var v = valuesArray[i].trim(); |
|
if (!v) { |
|
continue |
|
} |
|
// 如果是最后一个元素,直接push,不需要再处理了, 因为最后一个肯定不是key |
|
if (i === valuesArray.length -1) { |
|
cleanValues.push(v); |
|
continue |
|
} |
|
v = v.split(' '); |
|
// 如果长度是1,直接push上 |
|
// 如果长度不是1,根据空格分隔后,最后面的是key |
|
if (v.length === 1) { |
|
cleanValues.push(v[0]); |
|
} else { |
|
var leaveData = v.slice(0, -1).join(' ').trim(); |
|
cleanValues.push(leaveData); |
|
cleanValues.push(v.slice(-1)[0]); |
|
} |
|
} |
|
var filter = {}; |
|
var key = ''; |
|
for (i=0; i<cleanValues.length; i++) { |
|
if (i%2 === 0) { |
|
key = cleanValues[i] |
|
} else { |
|
value = cleanValues[i]; |
|
filter[key] = value |
|
} |
|
} |
|
return filter; |
|
} |
|
|
|
|
|
var jumpserver = {}; |
|
jumpserver.checked = false; |
|
jumpserver.selected = {}; |
|
jumpserver.language = { |
|
processing: gettext('Loading') + '...', |
|
search: gettext('Search'), |
|
select: { |
|
rows: { |
|
_: gettext("Selected item %d"), |
|
0: "" |
|
} |
|
}, |
|
lengthMenu: gettext("Per page _MENU_"), |
|
info: gettext('Displays the results of items _START_ to _END_; A total of _TOTAL_ entries'), |
|
infoFiltered: "", |
|
infoEmpty: "", |
|
zeroRecords: gettext("No match"), |
|
emptyTable: gettext('No record'), |
|
paginate: { |
|
first: "«", |
|
previous: "‹", |
|
next: "›", |
|
last: "»" |
|
} |
|
}; |
|
|
|
function setDataTablePagerLength(num) { |
|
$.fn.DataTable.ext.pager.numbers_length = num; |
|
} |
|
|
|
jumpserver.initDataTable = function (options) { |
|
// options = { |
|
// ele *: $('#dataTable_id'), |
|
// ajax_url *: '{% url 'users:user-list-api' %}', |
|
// columns *: [{data: ''}, ....], |
|
// dom: 'fltip', |
|
// i18n_url: '{% static "js/...../en-us.json" %}', |
|
// order: [[1, 'asc'], [2, 'asc'], ...], |
|
// buttons: ['excel', 'pdf', 'print'], |
|
// columnDefs: [{target: 0, createdCell: ()=>{}}, ...], |
|
// uc_html: '<a>header button</a>', |
|
// op_html: 'div.btn-group?', |
|
// paging: true |
|
// } |
|
setDataTablePagerLength(5); |
|
var ele = options.ele || $('.dataTable'); |
|
var columnDefs = [ |
|
{ |
|
targets: 0, |
|
orderable: false, |
|
width: "20px", |
|
createdCell: function (td, cellData) { |
|
$(td).html('<input type="checkbox" class="text-center ipt_check" id=99991937>'.replace('99991937', cellData)); |
|
} |
|
}, |
|
{ |
|
className: 'text-center', |
|
render: $.fn.dataTable.render.text(), |
|
targets: '_all' |
|
} |
|
]; |
|
columnDefs = options.columnDefs ? options.columnDefs.concat(columnDefs) : columnDefs; |
|
var select = { |
|
style: 'multi', |
|
selector: 'td:first-child' |
|
}; |
|
var table = ele.DataTable({ |
|
pageLength: options.pageLength || 15, |
|
dom: options.dom || '<"#uc.pull-left"><"pull-right"<"inline"l><"#fb.inline"><"inline"f><"#fa.inline">>tr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>', |
|
order: options.order || [], |
|
// select: options.select || 'multi', |
|
searchDelay: 800, |
|
buttons: [], |
|
columnDefs: columnDefs, |
|
ajax: { |
|
url: options.ajax_url, |
|
dataSrc: "" |
|
}, |
|
columns: options.columns || [], |
|
select: options.select || select, |
|
language: jumpserver.language, |
|
lengthMenu: [[10, 15, 25, 50, -1], [10, 15, 25, 50, "All"]] |
|
}); |
|
table.on('select', function (e, dt, type, indexes) { |
|
var $node = table[type](indexes).nodes().to$(); |
|
$node.find('input.ipt_check').prop('checked', true); |
|
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true |
|
}).on('deselect', function (e, dt, type, indexes) { |
|
var $node = table[type](indexes).nodes().to$(); |
|
$node.find('input.ipt_check').prop('checked', false); |
|
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false |
|
}).on('draw', function () { |
|
$('#op').html(options.op_html || ''); |
|
$('#uc').html(options.uc_html || ''); |
|
$('[data-toggle="popover"]').popover({ |
|
html: true, |
|
placement: 'bottom', |
|
trigger: 'click', |
|
container: 'body' |
|
}).on('click', function (e) { |
|
$('[data-toggle="popover"]').not(this).popover('hide'); |
|
}); |
|
}); |
|
$('.ipt_check_all').on('click', function () { |
|
if ($(this).prop("checked")) { |
|
$(this).closest('table').find('.ipt_check').prop('checked', true); |
|
jumpserver.checked = true; |
|
table.rows({search: 'applied', page: 'current'}).select(); |
|
} else { |
|
$(this).closest('table').find('.ipt_check').prop('checked', false); |
|
jumpserver.checked = false; |
|
table.rows({search: 'applied', page: 'current'}).deselect(); |
|
} |
|
}); |
|
|
|
return table; |
|
}; |
|
|
|
jumpserver.initStaticTable = function (selector) { |
|
$(selector).DataTable({ |
|
"searching": false, |
|
"bInfo": false, |
|
"paging": false, |
|
"order": [], |
|
"language": jumpserver.language |
|
}); |
|
}; |
|
|
|
jumpserver.initServerSideDataTable = function (options) { |
|
// options = { |
|
// ele *: $('#dataTable_id'), |
|
// ajax_url *: '{% url 'users:user-list-api' %}', |
|
// select_style: 'multi', |
|
// columns *: [{data: ''}, ....], |
|
// dom: 'fltip', |
|
// i18n_url: '{% static "js/...../en-us.json" %}', |
|
// order: [[1, 'asc'], [2, 'asc'], ...], |
|
// buttons: ['excel', 'pdf', 'print'], |
|
// columnDefs: [{target: 0, createdCell: ()=>{}}, ...], |
|
// uc_html: '<a>header button</a>', |
|
// op_html: 'div.btn-group?', |
|
// paging: true, |
|
// paging_numbers_length: 5; |
|
// hideDefaultDefs: false; |
|
// } |
|
var pagingNumbersLength = 5; |
|
if (options.paging_numbers_length){ |
|
pagingNumbersLength = options.paging_numbers_length; |
|
} |
|
setDataTablePagerLength(pagingNumbersLength); |
|
var ele = options.ele || $('.dataTable'); |
|
var columnDefs = [ |
|
{ |
|
targets: 0, |
|
orderable: false, |
|
width: "20px", |
|
createdCell: function (td, cellData) { |
|
var data = '<input type="checkbox" class="text-center ipt_check" id=Id>'.replace('Id', cellData); |
|
$(td).html(data); |
|
} |
|
}, |
|
{ |
|
targets: '_all', |
|
className: 'text-center', |
|
render: $.fn.dataTable.render.text() |
|
} |
|
]; |
|
if (options.hideDefaultDefs) { |
|
columnDefs = []; |
|
} |
|
var select_style = options.select_style || 'multi'; |
|
columnDefs = options.columnDefs ? options.columnDefs.concat(columnDefs) : columnDefs; |
|
var select = { |
|
style: select_style, |
|
selector: 'td:first-child' |
|
}; |
|
var dom = '<"#uc.pull-left"> <"pull-right"<"#lb.inline"> <"inline"l> <"#fb.inline"> <"inline"f><"#fa.inline">>' + |
|
'tr' + |
|
'<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>'; |
|
var table = ele.DataTable({ |
|
pageLength: options.pageLength || 15, |
|
// dom: options.dom || '<"#uc.pull-left">fltr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>', |
|
// dom: options.dom || '<"#uc.pull-left"><"pull-right"<"inline"l><"#fb.inline"><"inline"<"table-filter"f>><"#fa.inline">>tr<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>', |
|
dom: options.dom || dom, |
|
order: options.order || [], |
|
buttons: [], |
|
columnDefs: columnDefs, |
|
serverSide: true, |
|
processing: true, |
|
searchDelay: 800, |
|
oSearch: options.oSearch, |
|
ajax: { |
|
url: options.ajax_url, |
|
error: function (jqXHR, textStatus, errorThrown) { |
|
if (jqXHR.responseText && jqXHR.responseText.indexOf("%(value)s") !== -1 ) { |
|
return |
|
} |
|
var msg = gettext("Unknown error occur"); |
|
if (jqXHR.responseJSON) { |
|
if (jqXHR.responseJSON.error) { |
|
msg = jqXHR.responseJSON.error |
|
} else if (jqXHR.responseJSON.msg) { |
|
msg = jqXHR.responseJSON.msg |
|
} |
|
} |
|
alert(msg) |
|
}, |
|
data: function (data) { |
|
delete data.columns; |
|
if (data.length !== null) { |
|
data.limit = data.length; |
|
delete data.length; |
|
} |
|
if (data.start !== null) { |
|
data.offset = data.start; |
|
delete data.start; |
|
} |
|
if (data.search !== null) { |
|
var searchValue = data.search.value; |
|
var searchFilter = parseTableFilter(searchValue); |
|
if (Object.keys(searchFilter).length === 0) { |
|
data.search = searchValue; |
|
} else { |
|
data.search = ''; |
|
$.each(searchFilter, function (k, v) { |
|
data[k] = v |
|
}) |
|
} |
|
} |
|
if (data.order !== null && data.order.length === 1) { |
|
var col = data.order[0].column; |
|
var order = options.columns[col].data; |
|
if (data.order[0].dir === "desc") { |
|
order = "-" + order; |
|
} |
|
data.order = order; |
|
} |
|
}, |
|
dataFilter: function (data) { |
|
var json = jQuery.parseJSON(data); |
|
json.recordsTotal = json.count; |
|
json.recordsFiltered = json.count; |
|
return JSON.stringify(json); // return JSON string |
|
}, |
|
dataSrc: "results" |
|
}, |
|
columns: options.columns || [], |
|
select: options.select || select, |
|
language: jumpserver.language, |
|
lengthMenu: options.lengthMenu || [[15, 25, 50, 9999], [15, 25, 50, 'All']] |
|
}); |
|
table.selected = []; |
|
table.selected_rows = []; |
|
table.on('select', function (e, dt, type, indexes) { |
|
var $node = table[type](indexes).nodes().to$(); |
|
$node.find('input.ipt_check').prop('checked', true); |
|
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = true; |
|
if (type === 'row') { |
|
var rows = table.rows(indexes).data(); |
|
$.each(rows, function (id, row) { |
|
if (row.id && $.inArray(row.id, table.selected) === -1) { |
|
if (select.style === 'multi'){ |
|
table.selected.push(row.id); |
|
table.selected_rows.push(row); |
|
} |
|
else{ |
|
table.selected = [row.id]; |
|
table.selected_rows = [row]; |
|
} |
|
} |
|
}) |
|
} |
|
}).on('deselect', function (e, dt, type, indexes) { |
|
var $node = table[type](indexes).nodes().to$(); |
|
$node.find('input.ipt_check').prop('checked', false); |
|
jumpserver.selected[$node.find('input.ipt_check').prop('id')] = false; |
|
if (type === 'row') { |
|
var rows = table.rows(indexes).data(); |
|
$.each(rows, function (id, row) { |
|
if (row.id) { |
|
var index = table.selected.indexOf(row.id); |
|
if (index > -1) { |
|
table.selected.splice(index, 1); |
|
table.selected_rows.splice(index, 1); |
|
} |
|
} |
|
}) |
|
} |
|
}).on('draw', function () { |
|
$('[data-toggle="popover"]').popover({ |
|
html: true, |
|
placement: 'bottom', |
|
trigger: 'click', |
|
container: 'body' |
|
}).on('click', function (e) { |
|
$('[data-toggle="popover"]').not(this).popover('hide'); |
|
}); |
|
var table_data = []; |
|
$.each(table.rows().data(), function (id, row) { |
|
if (row.id) { |
|
table_data.push(row.id) |
|
} |
|
}); |
|
|
|
$.each(table.selected, function (id, data) { |
|
var index = table_data.indexOf(data); |
|
if (index > -1) { |
|
table.rows(index).select() |
|
} |
|
}); |
|
}).on("init", function () { |
|
$('#op').html(options.op_html || ''); |
|
$('#uc').html(options.uc_html || ''); |
|
$('#fb').html(options.fb_html || ''); |
|
$('#fa').html(options.fa_html || ''); |
|
$('#lb').html(options.lb_html || ''); |
|
}); |
|
var table_id = table.settings()[0].sTableId; |
|
$('#' + table_id + ' .ipt_check_all').on('click', function () { |
|
if (select_style !== 'multi') { |
|
return |
|
} |
|
if ($(this).prop("checked")) { |
|
$(this).closest('table').find('.ipt_check').prop('checked', true); |
|
table.rows({search: 'applied', page: 'current'}).select(); |
|
} else { |
|
$(this).closest('table').find('.ipt_check').prop('checked', false); |
|
table.rows({search: 'applied', page: 'current'}).deselect(); |
|
} |
|
}); |
|
|
|
// jumpserver.table = table; |
|
return table; |
|
}; |
|
|
|
/** |
|
* 替换所有匹配exp的字符串为指定字符串 |
|
* @param exp 被替换部分的正则 |
|
* @param newStr 替换成的字符串 |
|
*/ |
|
String.prototype.replaceAll = function (exp, newStr) { |
|
return this.replace(new RegExp(exp, "gm"), newStr); |
|
}; |
|
|
|
/** |
|
* 原型:字符串格式化 |
|
* @param args 格式化参数值 |
|
*/ |
|
String.prototype.format = function (args) { |
|
var result = this; |
|
if (arguments.length < 1) { |
|
return result; |
|
} |
|
|
|
var data = arguments; |
|
if (arguments.length == 1 && typeof (args) == "object") { |
|
data = args; |
|
} |
|
for (var key in data) { |
|
var value = data[key]; |
|
if (undefined != value) { |
|
result = result.replaceAll("\\{" + key + "\\}", value); |
|
} |
|
} |
|
return result; |
|
}; |
|
|
|
function setCookie(key, value, time) { |
|
var expires = new Date(); |
|
if (!time) { |
|
time = expires.getTime() + (24 * 60 * 60 * 1000); |
|
} |
|
expires.setTime(time); |
|
document.cookie = key + '=' + value + ';expires=' + expires.toUTCString() + ';path=/'; |
|
} |
|
|
|
|
|
function delCookie(key) { |
|
var expires = new Date(); |
|
expires.setTime(expires.getTime() - 1); |
|
var val = getCookie(key); |
|
if (val !== null) { |
|
document.cookie = key + '=' + val + ";expires" + expires.toUTCString() + ';path=/'; |
|
} |
|
} |
|
|
|
function createPopover(dataset, title, callback) { |
|
if (callback !== undefined) { |
|
var new_dataset = []; |
|
$.each(dataset, function (index, value) { |
|
new_dataset.push(callback(value)) |
|
}); |
|
dataset = new_dataset; |
|
} |
|
var data_content = dataset.join("<br>"); |
|
var html = "<a data-toggle='popover' data-content='" + data_content + "'>" + dataset.length + "</a>"; |
|
return html; |
|
} |
|
|
|
|
|
$(function () { |
|
(function ($) { |
|
$.getUrlParam = function (name) { |
|
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); |
|
var r = window.location.search.substr(1).match(reg); |
|
if (r != null) return unescape(r[2]); |
|
return null; |
|
} |
|
})(jQuery); |
|
}); |
|
|
|
function getUrlParam(name) { |
|
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); |
|
var r = window.location.search.substr(1).match(reg); |
|
if (r != null) return unescape(r[2]); |
|
return null; |
|
} |
|
|
|
function setUrlParam(url, name, value) { |
|
var urlArray = url.split("?"); |
|
if (urlArray.length === 1) { |
|
url += "?" + name + "=" + value; |
|
} else { |
|
var oriParam = urlArray[1].split("&"); |
|
var oriParamMap = {}; |
|
$.each(oriParam, function (index, value) { |
|
var v = value.split("="); |
|
oriParamMap[v[0]] = v[1]; |
|
}); |
|
oriParamMap[name] = value; |
|
url = urlArray[0] + "?"; |
|
var newParam = []; |
|
$.each(oriParamMap, function (index, value) { |
|
newParam.push(index + "=" + value); |
|
}); |
|
url += newParam.join("&") |
|
} |
|
return url |
|
} |
|
|
|
// Password check rules |
|
var rules_short_map_id = { |
|
'min': 'id_security_password_min_length', |
|
'upper': 'id_security_password_upper_case', |
|
'lower': 'id_security_password_lower_case', |
|
'number': 'id_security_password_number', |
|
'special': 'id_security_password_special_char' |
|
}; |
|
|
|
var rules_id_map_label = { |
|
'id_security_password_min_length': gettext('Password minimum length {N} bits'), |
|
'id_security_password_upper_case': gettext('Must contain capital letters'), |
|
'id_security_password_lower_case': gettext('Must contain lowercase letters'), |
|
'id_security_password_number': gettext('Must contain numeric characters'), |
|
'id_security_password_special_char': gettext('Must contain special characters') |
|
}; |
|
|
|
function getRuleLabel(rule) { |
|
var label = ''; |
|
if (rule.key === rules_short_map_id['min']) { |
|
label = rules_id_map_label[rule.key].replace('{N}', rule.value) |
|
} else { |
|
label = rules_id_map_label[rule.key] |
|
} |
|
return label |
|
} |
|
|
|
// 校验密码-改变规则颜色 |
|
function checkPasswordRules(password, minLength) { |
|
if (wordMinLength(password, minLength)) { |
|
$('#' + rules_short_map_id['min']).css('color', 'green') |
|
} else { |
|
$('#' + rules_short_map_id['min']).css('color', '#908a8a') |
|
} |
|
|
|
if (wordUpperCase(password)) { |
|
$('#' + rules_short_map_id['upper']).css('color', 'green') |
|
} else { |
|
$('#' + rules_short_map_id['upper']).css('color', '#908a8a') |
|
} |
|
|
|
if (wordLowerCase(password)) { |
|
$('#' + rules_short_map_id['lower']).css('color', 'green') |
|
} else { |
|
$('#' + rules_short_map_id['lower']).css('color', '#908a8a') |
|
} |
|
|
|
if (wordNumber(password)) { |
|
$('#' + rules_short_map_id['number']).css('color', 'green') |
|
} else { |
|
$('#' + rules_short_map_id['number']).css('color', '#908a8a') |
|
} |
|
|
|
if (wordSpecialChar(password)) { |
|
$('#' + rules_short_map_id['special']).css('color', 'green') |
|
} else { |
|
$('#' + rules_short_map_id['special']).css('color', '#908a8a') |
|
} |
|
} |
|
|
|
// 最小长度 |
|
function wordMinLength(word, minLength) { |
|
//var minLength = {{ min_length }}; |
|
var re = new RegExp("^(.{" + minLength + ",})$"); |
|
return word.match(re) |
|
} |
|
|
|
// 大写字母 |
|
function wordUpperCase(word) { |
|
return word.match(/([A-Z]+)/) |
|
} |
|
|
|
// 小写字母 |
|
function wordLowerCase(word) { |
|
return word.match(/([a-z]+)/) |
|
} |
|
|
|
// 数字字符 |
|
function wordNumber(word) { |
|
return word.match(/([\d]+)/) |
|
} |
|
|
|
// 特殊字符 |
|
function wordSpecialChar(word) { |
|
return word.match(/[`,~,!,@,#,\$,%,\^,&,\*,\(,\),\-,_,=,\+,\{,\},\[,\],\|,\\,;,',:,",\,,\.,<,>,\/,\?]+/) |
|
} |
|
|
|
|
|
// 显示弹窗密码规则 |
|
function popoverPasswordRules(password_check_rules, $el) { |
|
var message = ""; |
|
jQuery.each(password_check_rules, function (idx, rule) { |
|
message += "<li id=" + rule.key + " style='list-style-type:none;'> <i class='fa fa-check-circle-o' style='margin-right:10px;' ></i>" + getRuleLabel(rule) + "</li>"; |
|
}); |
|
//$('#id_password_rules').html(message); |
|
$el.html(message) |
|
} |
|
|
|
// 初始化弹窗popover |
|
function initPopover($container, $progress, $idPassword, $el, password_check_rules, i18n_fallback) { |
|
options = {}; |
|
// User Interface |
|
options.ui = { |
|
container: $container, |
|
viewports: { |
|
progress: $progress |
|
//errors: $('.popover-content') |
|
}, |
|
showProgressbar: true, |
|
showVerdictsInsideProgressBar: true |
|
}; |
|
options.i18n = { |
|
fallback: i18n_fallback, |
|
t: function (key) { |
|
var result = ''; |
|
result = options.i18n.fallback[key]; |
|
return result === key ? '' : result; |
|
} |
|
}; |
|
$idPassword.pwstrength(options); |
|
popoverPasswordRules(password_check_rules, $el); |
|
} |
|
|
|
|
|
|
|
function rootNodeAddDom(ztree, callback) { |
|
var refreshIcon = "<a id='tree-refresh'><i class='fa fa-refresh'></i></a>"; |
|
var rootNode = ztree.getNodes()[0]; |
|
if (rootNode) { |
|
var $rootNodeRef = $("#" + rootNode.tId + "_a"); |
|
$rootNodeRef.after(refreshIcon); |
|
} else { |
|
$rootNodeRef = $('#' + ztree.setting.treeId); |
|
$rootNodeRef.html(refreshIcon); |
|
} |
|
var refreshIconRef = $('#tree-refresh'); |
|
refreshIconRef.bind('click', function () { |
|
ztree.destroy(); |
|
callback() |
|
}) |
|
} |
|
|
|
function APIExportCSV(props) { |
|
/* |
|
{ |
|
listUrl: |
|
objectsId: |
|
template: |
|
table: |
|
params: |
|
} |
|
*/ |
|
var _listUrl = props.listUrl; |
|
var _objectsId = props.objectsId; |
|
var _template = props.template; |
|
var _table = props.table; |
|
var _params = props.params || {}; |
|
|
|
var tableParams = _table.ajax.params(); |
|
var exportUrl = setUrlParam(_listUrl, 'format', 'csv'); |
|
if (_template) { |
|
exportUrl = setUrlParam(exportUrl, 'template', _template) |
|
} |
|
for (var k in tableParams) { |
|
if (datatableInternalParams.includes(k)) { |
|
continue |
|
} |
|
if (!tableParams[k]) { |
|
continue |
|
} |
|
exportUrl = setUrlParam(exportUrl, k, tableParams[k]) |
|
} |
|
for (var k in _params) { |
|
exportUrl = setUrlParam(exportUrl, k, tableParams[k]) |
|
} |
|
|
|
if (!_objectsId) { |
|
console.log(exportUrl); |
|
window.open(exportUrl); |
|
return |
|
} |
|
|
|
requestApi({ |
|
url: '/api/v1/common/resources/cache/', |
|
data: JSON.stringify({resources: _objectsId}), |
|
method: "POST", |
|
flash_message: false, |
|
success: function (data) { |
|
exportUrl = setUrlParam(exportUrl, 'spm', data.spm); |
|
console.log(exportUrl); |
|
window.open(exportUrl); |
|
}, |
|
failed: function () { |
|
toastr.error(gettext('Export failed')); |
|
} |
|
}); |
|
} |
|
|
|
function APIExportData(props) { |
|
props = props || {}; |
|
$.ajax({ |
|
url: '/api/common/v1/resources/cache/', |
|
type: props.method || "POST", |
|
data: props.body, |
|
contentType: props.content_type || "application/json; charset=utf-8", |
|
dataType: props.data_type || "json", |
|
success: function (data) { |
|
var export_url = props.success_url; |
|
var params = props.params || {}; |
|
params['format'] = props.format; |
|
params['spm'] = data.spm; |
|
for (var k in params) { |
|
export_url = setUrlParam(export_url, k, params[k]) |
|
} |
|
window.open(export_url); |
|
}, |
|
error: function () { |
|
toastr.error(gettext('Export failed')); |
|
} |
|
}) |
|
} |
|
|
|
function APIImportData(props) { |
|
props = props || {}; |
|
$.ajax({ |
|
url: props.url, |
|
type: props.method || "POST", |
|
processData: false, |
|
data: props.body, |
|
contentType: props.content_type || 'text/csv', |
|
success: function (data) { |
|
if (props.method === 'POST') { |
|
$('#created_failed').html(''); |
|
$('#created_failed_detail').html(''); |
|
$('#success_created').html(gettext("Import Success")); |
|
$('#success_created_detail').html("Count" + ": " + data.length); |
|
} else { |
|
$('#updated_failed').html(''); |
|
$('#updated_failed_detail').html(''); |
|
$('#success_updated').html(gettext("Update Success")); |
|
$('#success_updated_detail').html(gettext("Count") + ": " + data.length); |
|
} |
|
|
|
props.data_table.ajax.reload() |
|
}, |
|
error: function (error) { |
|
var data = error.responseJSON; |
|
console.log(data); |
|
if (data instanceof Array) { |
|
var html = ''; |
|
var li = ''; |
|
var err = ''; |
|
$.each(data, function (index, item) { |
|
err = ''; |
|
for (var prop in item) { |
|
err += prop + ": " + item[prop][0] + " " |
|
} |
|
if (err) { |
|
li = "<li>" + "Line " + (++index) + ". " + err + "</li>"; |
|
html += li |
|
} |
|
}); |
|
html = "<ul>" + html + "</ul>" |
|
} else { |
|
html = error.responseText |
|
} |
|
if (props.method === 'POST') { |
|
$('#success_created').html(''); |
|
$('#success_created_detail').html(''); |
|
$('#created_failed').html(gettext("Import failed")); |
|
$('#created_failed_detail').html(html); |
|
} else { |
|
$('#success_updated').html(''); |
|
$('#success_updated_detail').html(''); |
|
$('#updated_failed').html(gettext("Update failed")); |
|
$('#updated_failed_detail').html(html); |
|
} |
|
} |
|
}) |
|
} |
|
|
|
|
|
function htmlEscape(d) { |
|
return typeof d === 'string' ? |
|
d.replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"') : |
|
d; |
|
} |
|
|
|
function objectAttrsIsList(obj, attrs) { |
|
attrs.forEach(function (attr) { |
|
if (!obj[attr]) { |
|
obj[attr] = [] |
|
} else if (obj[attr] && !(obj[attr] instanceof Array)) { |
|
obj[attr] = [obj[attr]] |
|
} |
|
}) |
|
} |
|
|
|
function objectAttrsIsDatetime(obj, attrs) { |
|
attrs.forEach(function (attr) { |
|
obj[attr] = toSafeDateISOStr(obj[attr]); |
|
}) |
|
} |
|
|
|
function objectAttrsIsBool(obj, attrs) { |
|
attrs.forEach(function (attr) { |
|
if (!obj[attr]) { |
|
obj[attr] = false |
|
} else { |
|
obj[attr] = ['on', '1', 'true', 'True'].includes(obj[attr]); |
|
} |
|
}) |
|
} |
|
|
|
function objectAttrsIsNumber(obj, attrs) { |
|
attrs.forEach(function (attr) { |
|
if (!obj[attr]) { |
|
obj[attr] = null; |
|
} |
|
}) |
|
} |
|
|
|
function cleanDateStr(d) { |
|
for (var i = 0; i < 3; i++) { |
|
if (!isNaN(Date.parse(d))) { |
|
return d; |
|
} |
|
if (!isNaN(Number(d))) { |
|
return d; |
|
} |
|
switch (i) { |
|
case 0: |
|
d = d.replaceAll('-', '/'); |
|
break; |
|
case 1: |
|
d = d.split('+')[0].trimRight(); |
|
break; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
function safeDate(s) { |
|
s = cleanDateStr(s); |
|
return new Date(s) |
|
} |
|
|
|
function toSafeDateISOStr(s) { |
|
var d = safeDate(s); |
|
return d.toISOString(); |
|
} |
|
|
|
function toSafeLocalDateStr(d) { |
|
var date = safeDate(d); |
|
// var date_s = date.toLocaleString(getUserLang(), {hour12: false}); |
|
var date_s = date.toLocaleString(getUserLang(), {hourCycle: "h23"}); |
|
return date_s.split("/").join('-') |
|
} |
|
|
|
function getUrlParams(url) { |
|
url = url.split("?"); |
|
var params = ""; |
|
if (url.length === 2) { |
|
params = url[1]; |
|
} |
|
return params |
|
} |
|
|
|
function getTimeUnits(u) { |
|
var units = { |
|
"d": "天", |
|
"h": "时", |
|
"m": "分", |
|
"s": "秒", |
|
}; |
|
if (getUserLang() === "zh-CN") { |
|
return units[u] |
|
} |
|
return u |
|
} |
|
|
|
function timeOffset(a, b) { |
|
var start = safeDate(a); |
|
var end = safeDate(b); |
|
var offset = (end - start) / 1000; |
|
return readableSecond(offset) |
|
} |
|
|
|
function readableSecond(offset) { |
|
var days = offset / 3600 / 24; |
|
var hours = offset / 3600; |
|
var minutes = offset / 60; |
|
var seconds = offset; |
|
|
|
if (days > 1) { |
|
return days.toFixed(1) + " " + getTimeUnits("d"); |
|
} else if (hours > 1) { |
|
return hours.toFixed(1) + " " + getTimeUnits("h"); |
|
} else if (minutes > 1) { |
|
return minutes.toFixed(1) + " " + getTimeUnits("m") |
|
} else if (seconds > 1) { |
|
return seconds.toFixed(1) + " " + getTimeUnits("s") |
|
} |
|
return "" |
|
} |
|
|
|
function readFile(ref) { |
|
var files = ref.prop('files'); |
|
var hasFile = files && files.length > 0; |
|
if (hasFile) { |
|
var reader = new FileReader();//新建一个FileReader |
|
reader.readAsText(files[0], "UTF-8");//读取文件 |
|
reader.onload = function (evt) { //读取完文件之后会回来这里 |
|
ref.trigger("onload", evt.target.result); |
|
}; |
|
} else { |
|
ref.trigger("onload", null); |
|
} |
|
|
|
return ref |
|
} |
|
|
|
|
|
|
|
function select2AjaxInit(option) { |
|
/* |
|
{ |
|
selector: |
|
url: , |
|
disabledData: , |
|
displayFormat, |
|
idFormat, |
|
} |
|
*/ |
|
var selector = option.selector; |
|
var url = option.url; |
|
var disabledData = option.disabledData; |
|
var displayFormat = option.displayFormat || function (data) { |
|
return data.name; |
|
}; |
|
var idFormat = option.idFormat || function (data) { |
|
return data.id; |
|
}; |
|
|
|
return $(selector).select2({ |
|
closeOnSelect: false, |
|
ajax: { |
|
url: url, |
|
data: function (params) { |
|
var page = params.page || 1; |
|
var query = { |
|
search: params.term, |
|
offset: (page - 1) * 10, |
|
limit: 10 |
|
}; |
|
return query |
|
}, |
|
processResults: function (data) { |
|
var results = $.map(data.results, function (v, i) { |
|
var display = displayFormat(v); |
|
var id = idFormat(v); |
|
var d = {id: id, text: display}; |
|
if (disabledData && disabledData.indexOf(v.id) !== -1) { |
|
d.disabled = true; |
|
} |
|
return d; |
|
}); |
|
var more = !!data.next; |
|
return {results: results, pagination: {"more": more}} |
|
} |
|
}, |
|
}) |
|
|
|
} |
|
|
|
function usersSelect2Init(selector, url, disabledData) { |
|
if (!url) { |
|
url = '/api/v1/users/users/' |
|
} |
|
function displayFormat(v) { |
|
return v.name + '(' + v.username +')'; |
|
} |
|
var option = { |
|
url: url, |
|
selector: selector, |
|
disabledData: disabledData, |
|
displayFormat: displayFormat |
|
}; |
|
return select2AjaxInit(option) |
|
} |
|
|
|
|
|
function nodesSelect2Init(selector, url, disabledData) { |
|
if (!url) { |
|
url = '/api/v1/assets/nodes/' |
|
} |
|
function displayFormat(v) { |
|
return v.full_value; |
|
} |
|
var option = { |
|
url: url, |
|
selector: selector, |
|
disabledData: disabledData, |
|
displayFormat: displayFormat |
|
}; |
|
return select2AjaxInit(option) |
|
} |
|
|
|
function showCeleryTaskLog(taskId) { |
|
var url = '/ops/celery/task/taskId/log/'.replace('taskId', taskId); |
|
window.open(url, '', 'width=900,height=600') |
|
} |
|
|
|
function getUserLang(){ |
|
let userLangEN = document.cookie.indexOf('django_language=en'); |
|
if (userLangEN === -1){ |
|
return 'zh-CN' |
|
} |
|
else{ |
|
return 'en-US' |
|
} |
|
} |
|
|
|
function initDateRangePicker(selector, options) { |
|
if (!options) { |
|
options = {} |
|
} |
|
var zhLocale = { |
|
format: 'YYYY-MM-DD HH:mm', |
|
separator: ' ~ ', |
|
applyLabel: "应用", |
|
cancelLabel: "取消", |
|
resetLabel: "重置", |
|
daysOfWeek: ["日", "一", "二", "三", "四", "五", "六"],//汉化处理 |
|
monthNames: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], |
|
}; |
|
var enLocale = { |
|
format: "YYYY-MM-DD HH:mm", |
|
separator: " - ", |
|
applyLabel: "Apply", |
|
cancelLabel: "Cancel", |
|
resetLabel: "Reset", |
|
daysOfWeek: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], |
|
monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], |
|
}; |
|
var defaultOption = { |
|
singleDatePicker: true, |
|
showDropdowns: true, |
|
timePicker: true, |
|
timePicker24Hour: true, |
|
autoApply: true, |
|
}; |
|
if (getUserLang() === 'zh-CN') { |
|
defaultOption.locale = zhLocale; |
|
} |
|
else{ |
|
// en-US |
|
defaultOption.locale = enLocale; |
|
} |
|
options = Object.assign(defaultOption, options); |
|
return $(selector).daterangepicker(options); |
|
} |
|
|
|
function reloadPage() { |
|
setTimeout( function () {window.location.reload();}, 300); |
|
} |
|
|
|
function isEmptyObject(obj) { |
|
return Object.keys(obj).length === 0 |
|
} |
|
|
|
function getStatusIcon(status, mapping, title) { |
|
var navy = '<i class="fa fa-circle text-navy" title=""></i>'; |
|
var danger = '<i class="fa fa-circle text-danger" title=""></i>'; |
|
var warning = '<i class="fa fa-circle text-warning" title=""></i>'; |
|
var icons = { |
|
navy: navy, |
|
danger: danger, |
|
warning: warning |
|
}; |
|
var defaultMapping = { |
|
true: 'navy', |
|
false: 'danger', |
|
1: 'navy', |
|
0: 'danger', |
|
default: 'navy' |
|
}; |
|
if (!mapping) { |
|
mapping = defaultMapping; |
|
} |
|
var name = mapping[status] || mapping['default']; |
|
var icon = icons[name]; |
|
if (title) { |
|
icon = icon.replace('title=""', 'title="' + title + '"') |
|
} |
|
return icon; |
|
} |
|
|
|
|
|
function fillKey(key) { |
|
const KeyLength = 16 |
|
if (key.length > KeyLength) { |
|
key = key.slice(0, KeyLength) |
|
} |
|
const filledKey = Buffer.alloc(KeyLength) |
|
const keys = Buffer.from(key) |
|
for (let i = 0; i < keys.length; i++) { |
|
filledKey[i] = keys[i] |
|
} |
|
return filledKey |
|
} |
|
|
|
function aesEncrypt(text, originKey) { |
|
const key = CryptoJS.enc.Utf8.parse(fillKey(originKey)); |
|
return CryptoJS.AES.encrypt(text, key, { |
|
mode: CryptoJS.mode.ECB, |
|
padding: CryptoJS.pad.ZeroPadding |
|
}).toString(); |
|
} |
|
|
|
function rsaEncrypt(text, pubKey) { |
|
if (!text) { |
|
return text |
|
} |
|
const jsEncrypt = new JSEncrypt(); |
|
jsEncrypt.setPublicKey(pubKey); |
|
return jsEncrypt.encrypt(text); |
|
} |
|
|
|
function rsaDecrypt(cipher, pkey) { |
|
const jsEncrypt = new JSEncrypt(); |
|
jsEncrypt.setPrivateKey(pkey); |
|
return jsEncrypt.decrypt(cipher) |
|
} |
|
|
|
|
|
window.rsaEncrypt = rsaEncrypt |
|
window.rsaDecrypt = rsaDecrypt |
|
|
|
function encryptPassword(password) { |
|
if (!password) { |
|
return '' |
|
} |
|
const aesKey = (Math.random() + 1).toString(36).substring(2) |
|
// public key 是 base64 存储的 |
|
const rsaPublicKeyText = getCookie('jms_public_key') |
|
.replaceAll('"', '') |
|
const rsaPublicKey = atob(rsaPublicKeyText) |
|
const keyCipher = rsaEncrypt(aesKey, rsaPublicKey) |
|
const passwordCipher = aesEncrypt(password, aesKey) |
|
return `${keyCipher}:${passwordCipher}` |
|
} |
|
|
|
|
|
function randomString(length) { |
|
const characters ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; |
|
let result = ''; |
|
const charactersLength = characters.length; |
|
for ( let i = 0; i < length; i++ ) { |
|
result += characters.charAt(Math.floor(Math.random() * charactersLength)); |
|
} |
|
|
|
return result; |
|
} |
|
|
|
function testEncrypt() { |
|
const radio = [] |
|
const len2 = [] |
|
for (let i=1;i<4096;i++) { |
|
const password = randomString(i) |
|
const cipher = encryptPassword(password) |
|
len2.push([password.length, cipher.length]) |
|
radio.push(cipher.length/password.length) |
|
} |
|
return radio |
|
} |
|
|
|
window.encryptPassword = encryptPassword
|
|
|