215 lines
6.1 KiB
JavaScript
215 lines
6.1 KiB
JavaScript
|
layui.use(["table", "form", "layer"], function () {
|
|||
|
var table = layui.table;
|
|||
|
var form = layui.form;
|
|||
|
var layer = layui.layer;
|
|||
|
var $ = layui.$;
|
|||
|
|
|||
|
// 初始化表格
|
|||
|
table.render({
|
|||
|
elem: "#token-table",
|
|||
|
url: "/api/tokens",
|
|||
|
headers: [
|
|||
|
{
|
|||
|
Authorization: "Bearer " + localStorage.getItem("token"),
|
|||
|
},
|
|||
|
],
|
|||
|
toolbar: "#tableToolbar",
|
|||
|
defaultToolbar: ["filter", "exports", "print"],
|
|||
|
cols: [
|
|||
|
[
|
|||
|
{ type: "checkbox" },
|
|||
|
{ field: "token", title: "访问令牌", width: 320 },
|
|||
|
{ field: "deviceUID", title: "设备UID", width: 180 },
|
|||
|
{ field: "type", title: "令牌类型", width: 100 },
|
|||
|
{
|
|||
|
field: "status",
|
|||
|
title: "状态",
|
|||
|
width: 100,
|
|||
|
templet: function (d) {
|
|||
|
if (d.status === "active")
|
|||
|
return '<span class="layui-badge layui-bg-green">有效</span>';
|
|||
|
if (d.status === "revoked")
|
|||
|
return '<span class="layui-badge layui-bg-gray">已撤销</span>';
|
|||
|
return '<span class="layui-badge layui-bg-orange">已过期</span>';
|
|||
|
},
|
|||
|
},
|
|||
|
{ field: "expireTime", title: "过期时间", width: 160 },
|
|||
|
{ field: "lastUsed", title: "最后使用", width: 160 },
|
|||
|
{ field: "usageCount", title: "使用次数", width: 100 },
|
|||
|
{ field: "ipList", title: "IP限制", width: 200 },
|
|||
|
{ fixed: "right", title: "操作", toolbar: "#tableRowBar", width: 180 },
|
|||
|
],
|
|||
|
],
|
|||
|
page: true,
|
|||
|
parseData: function(res) {
|
|||
|
if (res.code === 401) {
|
|||
|
window.location.href = '/login';
|
|||
|
return;
|
|||
|
}
|
|||
|
return res;
|
|||
|
},
|
|||
|
});
|
|||
|
|
|||
|
// 表格工具栏事件
|
|||
|
table.on("toolbar(token-table)", function (obj) {
|
|||
|
var checkStatus = table.checkStatus(obj.config.id);
|
|||
|
|
|||
|
switch (obj.event) {
|
|||
|
case "refresh":
|
|||
|
table.reload("token-table");
|
|||
|
break;
|
|||
|
case "batchRevoke":
|
|||
|
var data = checkStatus.data;
|
|||
|
if (data.length === 0) {
|
|||
|
layer.msg("请选择要撤销的令牌");
|
|||
|
return;
|
|||
|
}
|
|||
|
layer.confirm("确定撤销选中的令牌吗?", function (index) {
|
|||
|
var tokens = data.map((item) => item.token);
|
|||
|
// 执行批量撤销
|
|||
|
Promise.all(
|
|||
|
tokens.map((token) =>
|
|||
|
fetch("/api/tokens/" + token, {
|
|||
|
method: "DELETE",
|
|||
|
headers: {
|
|||
|
Authorization: "Bearer " + localStorage.getItem("token"),
|
|||
|
},
|
|||
|
}).then((response) => response.json())
|
|||
|
)
|
|||
|
)
|
|||
|
.then(() => {
|
|||
|
layer.msg("批量撤销成功");
|
|||
|
table.reload("token-table");
|
|||
|
})
|
|||
|
.catch((error) => {
|
|||
|
layer.msg("批量撤销失败:" + error.message);
|
|||
|
});
|
|||
|
layer.close(index);
|
|||
|
});
|
|||
|
break;
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
// 行工具栏事件
|
|||
|
table.on("tool(token-table)", function (obj) {
|
|||
|
var data = obj.data;
|
|||
|
|
|||
|
switch (obj.event) {
|
|||
|
case "view":
|
|||
|
layer.alert(JSON.stringify(data, null, 2), {
|
|||
|
title: "令牌详情",
|
|||
|
});
|
|||
|
break;
|
|||
|
case "logs":
|
|||
|
layer.open({
|
|||
|
type: 2,
|
|||
|
title: "令牌使用日志",
|
|||
|
area: ["800px", "600px"],
|
|||
|
content: "/admin/token-logs.html?id=" + data.id,
|
|||
|
});
|
|||
|
break;
|
|||
|
case "revoke":
|
|||
|
layer.confirm("确定撤销该令牌吗?", function (index) {
|
|||
|
fetch("/api/tokens/" + data.token, {
|
|||
|
method: "DELETE",
|
|||
|
headers: {
|
|||
|
Authorization: "Bearer " + localStorage.getItem("token"),
|
|||
|
},
|
|||
|
})
|
|||
|
.then((response) => response.json())
|
|||
|
.then((result) => {
|
|||
|
if (result.error) {
|
|||
|
layer.msg(result.error);
|
|||
|
return;
|
|||
|
}
|
|||
|
layer.msg("撤销成功");
|
|||
|
obj.update({
|
|||
|
status: "revoked",
|
|||
|
});
|
|||
|
})
|
|||
|
.catch((error) => {
|
|||
|
layer.msg("撤销失败:" + error.message);
|
|||
|
});
|
|||
|
layer.close(index);
|
|||
|
});
|
|||
|
break;
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
// 搜索表单提交
|
|||
|
form.on("submit(search)", function (data) {
|
|||
|
table.reload("token-table", {
|
|||
|
where: data.field,
|
|||
|
});
|
|||
|
return false;
|
|||
|
});
|
|||
|
|
|||
|
// 创建令牌按钮点击事件
|
|||
|
$("#create-token").on("click", function () {
|
|||
|
// 加载设备列表
|
|||
|
fetch("/api/devices", {
|
|||
|
headers: {
|
|||
|
Authorization: "Bearer " + localStorage.getItem("token"),
|
|||
|
},
|
|||
|
})
|
|||
|
.then((response) => response.json())
|
|||
|
.then((result) => {
|
|||
|
var devices = result.data;
|
|||
|
var options = devices
|
|||
|
.map(
|
|||
|
(device) =>
|
|||
|
`<option value="${device.uid}">${device.uid} (${device.deviceModel})</option>`
|
|||
|
)
|
|||
|
.join("");
|
|||
|
|
|||
|
layer.open({
|
|||
|
type: 1,
|
|||
|
title: "创建访问令牌",
|
|||
|
area: ["500px", "400px"],
|
|||
|
content: $("#createTokenTpl").html(),
|
|||
|
success: function () {
|
|||
|
$("select[name=device_uid]").append(options);
|
|||
|
form.render("select");
|
|||
|
},
|
|||
|
});
|
|||
|
})
|
|||
|
.catch((error) => {
|
|||
|
layer.msg("加载设备列表失败:" + error.message);
|
|||
|
});
|
|||
|
});
|
|||
|
|
|||
|
// 创建令牌表单提交
|
|||
|
form.on("submit(tokenSubmit)", function (data) {
|
|||
|
var ipList = data.field.ip_list.split(/[,,\s]+/).filter((ip) => ip);
|
|||
|
|
|||
|
fetch("/api/tokens", {
|
|||
|
method: "POST",
|
|||
|
headers: {
|
|||
|
Authorization: "Bearer " + localStorage.getItem("token"),
|
|||
|
"Content-Type": "application/json",
|
|||
|
},
|
|||
|
body: JSON.stringify({
|
|||
|
device_uid: data.field.device_uid,
|
|||
|
token_type: data.field.token_type,
|
|||
|
expire_days: parseInt(data.field.expire_days),
|
|||
|
ip_list: ipList,
|
|||
|
}),
|
|||
|
})
|
|||
|
.then((response) => response.json())
|
|||
|
.then((result) => {
|
|||
|
if (result.error) {
|
|||
|
layer.msg(result.error);
|
|||
|
return;
|
|||
|
}
|
|||
|
layer.closeAll("page");
|
|||
|
layer.msg("创建成功");
|
|||
|
table.reload("token-table");
|
|||
|
})
|
|||
|
.catch((error) => {
|
|||
|
layer.msg("创建失败:" + error.message);
|
|||
|
});
|
|||
|
|
|||
|
return false;
|
|||
|
});
|
|||
|
});
|