mirror of
https://github.com/yhl452493373/frps-panel.git
synced 2026-04-04 06:16:59 +08:00
the first commit, finish almost all function what i need
This commit is contained in:
48
assets/lang/en.json
Normal file
48
assets/lang/en.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"User Manage": "User Manage",
|
||||
"User": "User",
|
||||
"Token": "Token",
|
||||
"Notes": "Notes",
|
||||
"Search": "Search",
|
||||
"Reset": "Reset",
|
||||
"New user": "New user",
|
||||
"Remove user": "Remove user",
|
||||
"Disable user": "Disable user",
|
||||
"will take sometime to make effective": " will take sometime to make effective",
|
||||
"Enable user": "Enable user",
|
||||
"Remove": "Remove",
|
||||
"Disable": "Disable",
|
||||
"Enable": "Enable",
|
||||
"Please input user account": "Please input user account",
|
||||
"Please input user token": "Please input user token",
|
||||
"Please input user notes": "Please input user notes",
|
||||
"Status": "Status",
|
||||
"Operation": "Operation",
|
||||
"Confirm": "Confirm",
|
||||
"Cancel": "Cancel",
|
||||
"Confirm to remove user": "Confirm to remove user ?",
|
||||
"Confirm to disable user": "Confirm to disable user ?",
|
||||
"Confirm to enable user": "Confirm to enable user ?",
|
||||
"Operate success": "Operate success",
|
||||
"Operate failed": "Operate failed",
|
||||
"Operate error": "Operate error",
|
||||
"Other error": "Other error",
|
||||
"Param error": "Param error",
|
||||
"User exist": "User exist",
|
||||
"Token cannot be empty": "Token cannot be empty",
|
||||
"Please check at least one user": "Please Check at least one user",
|
||||
"Operation confirm": "Operation confirm",
|
||||
"Empty data": "Empty data",
|
||||
"Allowed ports": "Allowed ports",
|
||||
"Please input allowed ports": "Please input allowed ports, example: 8081, 9000-9010",
|
||||
"Allowed domains": "Allowed domains",
|
||||
"Please input allowed domains": "Please input allowed domains, example: web01.domain.com,web02.domain.com",
|
||||
"Allowed subdomains": "Allowed subdomains",
|
||||
"Please input allowed subdomains": "Please input allowed subdomains, example: web01,web02",
|
||||
"Ports is invalid": "Ports is invalid",
|
||||
"Domains is invalid": "Domains is invalid",
|
||||
"Subdomains is invalid": "Subdomains is invalid",
|
||||
"Comment is invalid": "Comment is invalid, it cannot include line breaks",
|
||||
"Not limit": "Not limit",
|
||||
"None": "None"
|
||||
}
|
||||
48
assets/lang/zh.json
Normal file
48
assets/lang/zh.json
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"User Manage": "用户管理",
|
||||
"User": "用户名(user)",
|
||||
"Token": "凭证(meta_token)",
|
||||
"Notes": "备注",
|
||||
"Search": "搜索",
|
||||
"Reset": "重置",
|
||||
"New user": "新增用户",
|
||||
"Remove user": "删除用户",
|
||||
"Disable user": "禁用用户",
|
||||
"will take sometime to make effective": "需要一定时间才会生效",
|
||||
"Enable user": "启用用户",
|
||||
"Remove": "删除",
|
||||
"Disable": "禁用",
|
||||
"Enable": "启用",
|
||||
"Please input user account": "请输入用户名(user)",
|
||||
"Please input user token": "请输入Token(meta_token)",
|
||||
"Please input user notes": "请输入备注",
|
||||
"Status": "状态",
|
||||
"Operation": "操作",
|
||||
"Confirm": "确定",
|
||||
"Cancel": "取消",
|
||||
"Confirm to remove user": "确定删除用户 ?",
|
||||
"Confirm to disable user": "确定禁用用户 ?",
|
||||
"Confirm to enable user": "确定启用用户 ?",
|
||||
"Operate success": "操作成功",
|
||||
"Operate failed": "操作失败",
|
||||
"Operate error": "操作异常",
|
||||
"Other error": "其他异常",
|
||||
"Param error": "参数异常",
|
||||
"User exist": "用户已经存在",
|
||||
"Token cannot be empty": "Token 不能为空",
|
||||
"Please check at least one user": "请选中需要操作的用户",
|
||||
"Operation confirm": "操作确认",
|
||||
"Empty data": "无数据",
|
||||
"Allowed ports": "允许端口",
|
||||
"Please input allowed ports": "请输入允许使用的端口,如:8081, 9000-9010",
|
||||
"Allowed domains": "允许域名",
|
||||
"Please input allowed domains": "请输入允许使用的域名,如:web01.domain.com,web02.domain.com",
|
||||
"Allowed subdomains": "允许子域名",
|
||||
"Please input allowed subdomains": "请输入允许使用的端口,如:web01,web02",
|
||||
"Ports is invalid": "端口不正确",
|
||||
"Domains is invalid": "域名不正确",
|
||||
"Subdomains is invalid": "子域名不正确",
|
||||
"Comment is invalid": "备注不正确,不能包含换行",
|
||||
"Not limit": "无限制",
|
||||
"None": "无"
|
||||
}
|
||||
53
assets/static/css/index.css
Normal file
53
assets/static/css/index.css
Normal file
@@ -0,0 +1,53 @@
|
||||
body {
|
||||
padding: 15px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
#searchForm input {
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
#searchForm .layui-input-suffix,
|
||||
#searchForm .layui-input-prefix {
|
||||
line-height: 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#addUserForm {
|
||||
padding: 15px 15px 0 15px;
|
||||
}
|
||||
|
||||
#addUserForm .layui-form-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#addUserForm .layui-textarea {
|
||||
min-height: 80px;
|
||||
padding: 9px 10px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.layui-form-label {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.layui-input-block {
|
||||
margin-left: 170px;
|
||||
}
|
||||
|
||||
.layui-btn-sm {
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.layui-btn-xs {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.layui-btn-container{
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.layui-layer-btn > a[class^=layui-layer-btn]{
|
||||
line-height: 28px;
|
||||
}
|
||||
2186
assets/static/css/layui-theme-dark.css
Normal file
2186
assets/static/css/layui-theme-dark.css
Normal file
File diff suppressed because it is too large
Load Diff
563
assets/static/js/index.js
Normal file
563
assets/static/js/index.js
Normal file
@@ -0,0 +1,563 @@
|
||||
var $ = layui.$;
|
||||
$(function () {
|
||||
var apiType = {
|
||||
Remove: 1,
|
||||
Enable: 2,
|
||||
Disable: 3
|
||||
}
|
||||
|
||||
/**
|
||||
* verify comment is valid
|
||||
* @param comment
|
||||
*
|
||||
* @return {{valid:boolean, trim:string}}
|
||||
*/
|
||||
function verifyComment(comment) {
|
||||
var valid = true;
|
||||
if (comment.trim() !== '' && /[\n\t\r]/.test(comment)) {
|
||||
valid = false;
|
||||
}
|
||||
return {
|
||||
valid: valid,
|
||||
trim: comment.replace(/[\n\t\r]/g, '')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* verify ports is valid
|
||||
* @param ports
|
||||
*
|
||||
* @return {{valid:boolean, trim:string}}
|
||||
*/
|
||||
function verifyPorts(ports) {
|
||||
var valid = true;
|
||||
if (ports.trim() !== '') {
|
||||
try {
|
||||
ports.split(",").forEach(function (port) {
|
||||
if (/^\s*\d{1,5}\s*$/.test(port)) {
|
||||
if (parseInt(port) < 1 || parseInt(port) > 65535) {
|
||||
valid = false;
|
||||
}
|
||||
} else if (/^\s*\d{1,5}\s*-\s*\d{1,5}\s*$/.test(port)) {
|
||||
var portRange = port.split('-');
|
||||
if (parseInt(portRange[0]) < 1 || parseInt(portRange[0]) > 65535) {
|
||||
valid = false;
|
||||
} else if (parseInt(portRange[1]) < 1 || parseInt(portRange[1]) > 65535) {
|
||||
valid = false;
|
||||
} else if (parseInt(portRange[0]) > parseInt(portRange[1])) {
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
valid = false;
|
||||
}
|
||||
if (valid === false) {
|
||||
throw 'break';
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
return {
|
||||
valid: valid,
|
||||
trim: ports.replace(/\s/g, '')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* verify domains is valid
|
||||
* @param domains
|
||||
*
|
||||
* @return {{valid:boolean, trim:string}}
|
||||
*/
|
||||
function verifyDomains(domains) {
|
||||
var valid = true;
|
||||
if (domains.trim() !== '') {
|
||||
try {
|
||||
domains.split(',').forEach(function (domain) {
|
||||
if (!/^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62}){1,3}$/.test(domain.trim())) {
|
||||
valid = false;
|
||||
throw 'break';
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
return {
|
||||
valid: valid,
|
||||
trim: domains.replace(/\s/g, '')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* verify subdomains is valid
|
||||
* @param subdomains
|
||||
*
|
||||
* @return {{valid:boolean, trim:string}}
|
||||
*/
|
||||
function verifySubdomains(subdomains) {
|
||||
var valid = true;
|
||||
if (subdomains.trim() !== '') {
|
||||
try {
|
||||
subdomains.split(',').forEach(function (subdomain) {
|
||||
if (!/^[a-zA-z0-9][a-zA-Z0-9-]{0,19}$/.test(subdomain.trim())) {
|
||||
valid = false;
|
||||
throw 'break';
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
return {
|
||||
valid: valid,
|
||||
trim: subdomains.replace(/\s/g, '')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* load i18n language
|
||||
* @param lang {{}}
|
||||
*/
|
||||
function langLoaded(lang) {
|
||||
//set verify rules
|
||||
var verifyRules = {
|
||||
comment: function (value, item) {
|
||||
var result = verifyComment(value);
|
||||
if (!result.valid) {
|
||||
return lang['CommentInvalid'];
|
||||
}
|
||||
if (typeof item === "function") {
|
||||
item && item(result.trim);
|
||||
} else {
|
||||
$(item).val(result.trim);
|
||||
}
|
||||
},
|
||||
ports: function (value, item) {
|
||||
var result = verifyPorts(value);
|
||||
if (!result.valid) {
|
||||
return lang['PortsInvalid'];
|
||||
}
|
||||
if (typeof item === "function") {
|
||||
item && item(result.trim);
|
||||
} else {
|
||||
$(item).val(result.trim);
|
||||
}
|
||||
},
|
||||
domains: function (value, item) {
|
||||
var result = verifyDomains(value);
|
||||
if (!result.valid) {
|
||||
return lang['DomainsInvalid'];
|
||||
}
|
||||
if (typeof item === "function") {
|
||||
item && item(result.trim);
|
||||
} else {
|
||||
$(item).val(result.trim);
|
||||
}
|
||||
},
|
||||
subdomains: function (value, item) {
|
||||
var result = verifySubdomains(value);
|
||||
if (!result.valid) {
|
||||
return lang['SubdomainsInvalid'];
|
||||
}
|
||||
if (typeof item === "function") {
|
||||
item && item(result.trim);
|
||||
} else {
|
||||
$(item).val(result.trim);
|
||||
}
|
||||
}
|
||||
};
|
||||
layui.form.verify(verifyRules);
|
||||
|
||||
layui.table.render({
|
||||
elem: '#tokenTable',
|
||||
url: '/tokens',
|
||||
method: 'get',
|
||||
where: {},
|
||||
dataType: 'json',
|
||||
editTrigger: 'dblclick',
|
||||
page: navigator.language.indexOf("zh") === 0,
|
||||
toolbar: '#toolbarTemplate',
|
||||
defaultToolbar: false,
|
||||
text: {none: lang['EmptyData']},
|
||||
cols: [[
|
||||
{type: 'checkbox'},
|
||||
{field: 'user', title: lang['User'], width: 150, sort: true},
|
||||
{field: 'token', title: lang['Token'], width: 200, sort: true, edit: true},
|
||||
{field: 'comment', title: lang['Notes'], sort: true, edit: 'textarea'},
|
||||
{field: 'ports', title: lang['AllowedPorts'], sort: true, edit: 'textarea'},
|
||||
{field: 'domains', title: lang['AllowedDomains'], sort: true, edit: 'textarea'},
|
||||
{field: 'subdomains', title: lang['AllowedSubdomains'], sort: true, edit: 'textarea'},
|
||||
{
|
||||
field: 'status',
|
||||
title: lang['Status'],
|
||||
width: 100,
|
||||
templet: '<span>{{d.status? "' + lang['Enable'] + '":"' + lang['Disable'] + '"}}</span>',
|
||||
sort: true
|
||||
},
|
||||
{title: lang['Operation'], width: 150, toolbar: '#operationTemplate'}
|
||||
]]
|
||||
});
|
||||
|
||||
/**
|
||||
* update layui table data
|
||||
* @param obj table update obj
|
||||
* @param field update field
|
||||
* @param trim new value
|
||||
*/
|
||||
function updateTableField(obj, field, trim) {
|
||||
var newData = {};
|
||||
newData[field] = trim;
|
||||
obj.update(newData);
|
||||
}
|
||||
|
||||
layui.table.on('edit(tokenTable)', function (obj) {
|
||||
var field = obj.field;
|
||||
var value = obj.value;
|
||||
var oldValue = obj.oldValue;
|
||||
var before = $.extend(true, {}, obj.data);
|
||||
var after = $.extend(true, {}, obj.data);
|
||||
var verifyMsg = false;
|
||||
if (field === 'token') {
|
||||
if (value.trim() === '') {
|
||||
layui.layer.msg(lang['TokenEmpty'])
|
||||
return obj.reedit();
|
||||
}
|
||||
|
||||
before.token = oldValue;
|
||||
after.token = value;
|
||||
} else if (field === 'comment') {
|
||||
verifyMsg = verifyRules.comment(value, function (trim) {
|
||||
updateTableField(obj, field, trim)
|
||||
});
|
||||
if (verifyMsg) {
|
||||
layui.layer.msg(verifyMsg);
|
||||
return obj.reedit();
|
||||
}
|
||||
|
||||
before.comment = oldValue;
|
||||
after.comment = value;
|
||||
} else if (field === 'ports') {
|
||||
verifyMsg = verifyRules.ports(value, function (trim) {
|
||||
updateTableField(obj, field, trim)
|
||||
});
|
||||
if (verifyMsg) {
|
||||
layui.layer.msg(verifyMsg);
|
||||
return obj.reedit();
|
||||
}
|
||||
|
||||
before.ports = oldValue;
|
||||
after.ports = value;
|
||||
} else if (field === 'domains') {
|
||||
verifyMsg = verifyRules.domains(value, function (trim) {
|
||||
updateTableField(obj, field, trim)
|
||||
});
|
||||
if (verifyMsg) {
|
||||
layui.layer.msg(verifyMsg);
|
||||
return obj.reedit();
|
||||
}
|
||||
|
||||
before.domains = oldValue;
|
||||
after.domains = value;
|
||||
} else if (field === 'subdomains') {
|
||||
verifyMsg = verifyRules.subdomains(value, function (trim) {
|
||||
updateTableField(obj, field, trim)
|
||||
});
|
||||
if (verifyMsg) {
|
||||
layui.layer.msg(verifyMsg);
|
||||
return obj.reedit();
|
||||
}
|
||||
|
||||
before.subdomains = oldValue;
|
||||
after.subdomains = value;
|
||||
}
|
||||
|
||||
update(before, after);
|
||||
});
|
||||
|
||||
layui.table.on('toolbar(tokenTable)', function (obj) {
|
||||
var id = obj.config.id;
|
||||
var checkStatus = layui.table.checkStatus(id);
|
||||
switch (obj.event) {
|
||||
case 'add':
|
||||
addPopup();
|
||||
break
|
||||
case 'remove':
|
||||
batchRemovePopup(checkStatus.data);
|
||||
break
|
||||
case 'disable':
|
||||
batchDisablePopup(checkStatus.data);
|
||||
break
|
||||
case 'enable':
|
||||
batchEnablePopup(checkStatus.data);
|
||||
break
|
||||
}
|
||||
});
|
||||
layui.table.on('tool(tokenTable)', function (obj) {
|
||||
var data = obj.data;
|
||||
switch (obj.event) {
|
||||
case 'remove':
|
||||
removePopup(data);
|
||||
break;
|
||||
case 'disable':
|
||||
disablePopup(data);
|
||||
break;
|
||||
case 'enable':
|
||||
enablePopup(data);
|
||||
break
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* add user popup
|
||||
*/
|
||||
function addPopup() {
|
||||
layui.layer.open({
|
||||
type: 1,
|
||||
title: lang['NewUser'],
|
||||
area: ['500px'],
|
||||
content: layui.laytpl(document.getElementById('addTemplate').innerHTML).render(),
|
||||
btn: [lang['Confirm'], lang['Cancel']],
|
||||
btn1: function (index) {
|
||||
if (layui.form.validate('#addUserForm')) {
|
||||
add(layui.form.val('addUserForm'), index)
|
||||
}
|
||||
},
|
||||
btn2: function (index) {
|
||||
layui.layer.close(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* add user action
|
||||
* @param data {{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}} user data
|
||||
* @param index popup index
|
||||
*/
|
||||
function add(data, index) {
|
||||
var loading = layui.layer.load();
|
||||
$.ajax({
|
||||
url: '/add',
|
||||
type: 'post',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function (result) {
|
||||
if (result.success) {
|
||||
reloadTable();
|
||||
layui.layer.close(index);
|
||||
layui.layer.msg(lang['OperateSuccess'], function (index) {
|
||||
layui.layer.close(index);
|
||||
});
|
||||
} else {
|
||||
errorMsg(result);
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
layui.layer.close(loading);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* update user action
|
||||
* @param before {{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}} data before update
|
||||
* @param after {{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}} data after update
|
||||
*/
|
||||
function update(before, after) {
|
||||
var loading = layui.layer.load();
|
||||
$.ajax({
|
||||
url: '/update',
|
||||
type: 'post',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
before: before,
|
||||
after: after,
|
||||
}),
|
||||
success: function (result) {
|
||||
if (result.success) {
|
||||
layui.layer.msg(lang['OperateSuccess']);
|
||||
} else {
|
||||
errorMsg(result);
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
layui.layer.close(loading);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* batch remove user popup
|
||||
* @param data {[{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}]} user data list
|
||||
*/
|
||||
function batchRemovePopup(data) {
|
||||
if (data.length === 0) {
|
||||
layui.layer.msg(lang['ShouldCheckUser']);
|
||||
return;
|
||||
}
|
||||
layui.layer.confirm(lang['ConfirmRemoveUser'], {
|
||||
title: lang['OperationConfirm'],
|
||||
btn: [lang['Confirm'], lang['Cancel']]
|
||||
}, function (index) {
|
||||
operate(apiType.Remove, data, index);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* batch disable user popup
|
||||
* @param data {[{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}]} user data list
|
||||
*/
|
||||
function batchDisablePopup(data) {
|
||||
if (data.length === 0) {
|
||||
layui.layer.msg(lang['ShouldCheckUser']);
|
||||
return;
|
||||
}
|
||||
layui.layer.confirm(lang['ConfirmDisableUser'], {
|
||||
title: lang['OperationConfirm'],
|
||||
btn: [lang['Confirm'], lang['Cancel']]
|
||||
}, function (index) {
|
||||
operate(apiType.Disable, data, index);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* batch enable user popup
|
||||
* @param data {[{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}]} user data list
|
||||
*/
|
||||
function batchEnablePopup(data) {
|
||||
if (data.length === 0) {
|
||||
layui.layer.msg(lang['ShouldCheckUser']);
|
||||
return;
|
||||
}
|
||||
layui.layer.confirm(lang['ConfirmEnableUser'], {
|
||||
title: lang['OperationConfirm'],
|
||||
btn: [lang['Confirm'], lang['Cancel']]
|
||||
}, function (index) {
|
||||
operate(apiType.Enable, data, index);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* remove one user popup
|
||||
* @param data {{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}} user data
|
||||
*/
|
||||
function removePopup(data) {
|
||||
layui.layer.confirm(lang['ConfirmRemoveUser'], {
|
||||
title: lang['OperationConfirm'],
|
||||
btn: [lang['Confirm'], lang['Cancel']]
|
||||
}, function (index) {
|
||||
operate(apiType.Remove, [data], index);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* disable one user popup
|
||||
* @param data {{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}} user data
|
||||
*/
|
||||
function disablePopup(data) {
|
||||
layui.layer.confirm(lang['ConfirmDisableUser'], {
|
||||
title: lang['OperationConfirm'],
|
||||
btn: [lang['Confirm'], lang['Cancel']]
|
||||
}, function (index) {
|
||||
operate(apiType.Disable, [data], index);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* enable one user popup
|
||||
* @param data {{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}} user data
|
||||
*/
|
||||
function enablePopup(data) {
|
||||
layui.layer.confirm(lang['ConfirmEnableUser'], {
|
||||
title: lang['OperationConfirm'],
|
||||
btn: [lang['Confirm'], lang['Cancel']]
|
||||
}, function (index) {
|
||||
operate(apiType.Enable, [data], index);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* operate actions
|
||||
* @param type {apiType} action type
|
||||
* @param data {[{user:string, token:string, comment:string, status:boolean, ports:string, domains:string, subdomains:string}]} user data list
|
||||
* @param index popup index
|
||||
*/
|
||||
function operate(type, data, index) {
|
||||
var url;
|
||||
var extendMessage = '';
|
||||
if (type === apiType.Remove) {
|
||||
url = "/remove";
|
||||
extendMessage = ', ' + lang['RemoveUser'] + lang['TakeTimeMakeEffective'];
|
||||
} else if (type === apiType.Disable) {
|
||||
url = "/disable";
|
||||
extendMessage = ', ' + lang['RemoveUser'] + lang['TakeTimeMakeEffective'];
|
||||
} else if (type === apiType.Enable) {
|
||||
url = "/enable";
|
||||
} else {
|
||||
layer.layer.msg(lang['OperateError']);
|
||||
return;
|
||||
}
|
||||
var loading = layui.layer.load();
|
||||
$.post({
|
||||
url: url,
|
||||
type: 'post',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
users: data
|
||||
}),
|
||||
success: function (result) {
|
||||
if (result.success) {
|
||||
reloadTable();
|
||||
layui.layer.close(index);
|
||||
layui.layer.msg(lang['OperateSuccess'] + extendMessage, function (index) {
|
||||
layui.layer.close(index);
|
||||
});
|
||||
} else {
|
||||
errorMsg(result);
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
layui.layer.close(loading);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* reload user table
|
||||
*/
|
||||
function reloadTable() {
|
||||
var searchData = layui.form.val('searchForm');
|
||||
layui.table.reloadData('tokenTable', {
|
||||
where: searchData
|
||||
}, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* show error message popup
|
||||
* @param result
|
||||
*/
|
||||
function errorMsg(result) {
|
||||
var reason = lang['Other Error'];
|
||||
if (result.code === 1)
|
||||
reason = lang['ParamError'];
|
||||
else if (result.code === 2)
|
||||
reason = lang['UserExist'];
|
||||
layui.layer.msg(lang['OperateFailed'] + ',' + reason)
|
||||
}
|
||||
|
||||
/**
|
||||
* click event
|
||||
*/
|
||||
$(document).on('click.search', '#searchBtn', function () {
|
||||
reloadTable();
|
||||
return false;
|
||||
}).on('click.reset', '#resetBtn', function () {
|
||||
$('#searchForm')[0].reset();
|
||||
reloadTable();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
var langLoading = layui.layer.load()
|
||||
$.getJSON('/lang').done(langLoaded).always(function () {
|
||||
layui.layer.close(langLoading);
|
||||
});
|
||||
});
|
||||
1
assets/static/layui/css/layui.css
Normal file
1
assets/static/layui/css/layui.css
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/static/layui/font/iconfont.eot
Normal file
BIN
assets/static/layui/font/iconfont.eot
Normal file
Binary file not shown.
405
assets/static/layui/font/iconfont.svg
Normal file
405
assets/static/layui/font/iconfont.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 322 KiB |
BIN
assets/static/layui/font/iconfont.ttf
Normal file
BIN
assets/static/layui/font/iconfont.ttf
Normal file
Binary file not shown.
BIN
assets/static/layui/font/iconfont.woff
Normal file
BIN
assets/static/layui/font/iconfont.woff
Normal file
Binary file not shown.
BIN
assets/static/layui/font/iconfont.woff2
Normal file
BIN
assets/static/layui/font/iconfont.woff2
Normal file
Binary file not shown.
1
assets/static/layui/layui.js
Normal file
1
assets/static/layui/layui.js
Normal file
File diff suppressed because one or more lines are too long
124
assets/templates/index.html
Normal file
124
assets/templates/index.html
Normal file
@@ -0,0 +1,124 @@
|
||||
<!--suppress HtmlFormInputWithoutLabel -->
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<title>${ .UserManage }</title>
|
||||
<link rel="stylesheet" href="./static/layui/css/layui.css">
|
||||
<link rel="stylesheet" href="./static/css/layui-theme-dark.css">
|
||||
<link rel="stylesheet" href="./static/css/index.css">
|
||||
<script src="./static/layui/layui.js"></script>
|
||||
<script src="./static/js/index.js"></script>
|
||||
<style>
|
||||
.layui-table-cell:empty::after {
|
||||
content: '${ .NotLimit }';
|
||||
}
|
||||
|
||||
td[data-field=comment] .layui-table-cell:empty::after {
|
||||
content: '${ .None }';
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<form class="layui-form layui-row layui-col-space16" id="searchForm" lay-filter="searchForm">
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-input-wrap">
|
||||
<div class="layui-input-prefix">
|
||||
<i class="layui-icon layui-icon-username"></i>
|
||||
</div>
|
||||
<input type="text" name="user" value="" placeholder="${ .User }" class="layui-input" autocomplete="off"
|
||||
lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-input-wrap">
|
||||
<div class="layui-input-prefix">
|
||||
<i class="layui-icon layui-icon-vercode"></i>
|
||||
</div>
|
||||
<input type="text" name="token" placeholder="${ .Token }" class="layui-input" autocomplete="off"
|
||||
lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-input-wrap">
|
||||
<div class="layui-input-prefix">
|
||||
<i class="layui-icon layui-icon-note"></i>
|
||||
</div>
|
||||
<input type="text" name="comment" placeholder="${ .Notes }" class="layui-input" autocomplete="off"
|
||||
lay-affix="clear">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" id="searchBtn">${ .Search }</button>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-primary" type="reset" id="resetBtn">${ .Reset }</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<table id="tokenTable" lay-filter="tokenTable"></table>
|
||||
<script type="text/html" id="toolbarTemplate">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">${ .NewUser }</button>
|
||||
<button class="layui-btn layui-btn-sm" lay-event="remove">${ .RemoveUser }</button>
|
||||
<button class="layui-btn layui-btn-sm" lay-event="disable">${ .DisableUser }</button>
|
||||
<button class="layui-btn layui-btn-sm" lay-event="enable">${ .EnableUser }</button>
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/html" id="operationTemplate">
|
||||
<div class="layui-clear-space">
|
||||
<a class="layui-btn layui-btn-xs" lay-event="remove">${ .Remove }</a>
|
||||
{{# if (d.status) { }}
|
||||
<a class="layui-btn layui-btn-xs" lay-event="disable">${ .Disable }</a>
|
||||
{{# } else { }}
|
||||
<a class="layui-btn layui-btn-xs" lay-event="enable">${ .Enable }</a>
|
||||
{{# } }}
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/html" id="addTemplate">
|
||||
<div class="layui-form" id="addUserForm" lay-filter="addUserForm">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .User }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="user" placeholder="${ .PleaseInputUserAccount }" autocomplete="off"
|
||||
class="layui-input"
|
||||
lay-verify="required">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .Token }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="token" lay-verify="required" placeholder="${ .PleaseInputUserToken }"
|
||||
class="layui-input"
|
||||
autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">${ .Notes }</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="comment" lay-verify="comment" placeholder="${ .PleaseInputUserNotes }"
|
||||
autocomplete="off" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">${ .AllowedPorts }</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="ports" lay-verify="ports" placeholder="${ .PleaseInputAllowedPorts }"
|
||||
autocomplete="off" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">${ .AllowedDomains }</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="domains" lay-verify="domains" placeholder="${ .PleaseInputAllowedDomains }"
|
||||
autocomplete="off" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">${ .AllowedSubdomains }</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="subdomains" lay-verify="subdomains" placeholder="${ .PleaseInputAllowedSubdomains }"
|
||||
autocomplete="off" class="layui-textarea"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user