修复节点无法编辑的错误
This commit is contained in:
@@ -173,8 +173,12 @@
|
||||
const payload = await request(`${cfg.api.onlineDevices}?page=${page}&per_page=20`);
|
||||
state.devices = normalizeListPayload(payload);
|
||||
} else if (state.route === "user-ipv6-subscription") {
|
||||
const payload = await request(`${cfg.api.ipv6Base}/users?page=${page}&per_page=20`);
|
||||
const [payload, plans] = await Promise.all([
|
||||
request(`${cfg.api.ipv6Base}/users?page=${page}&per_page=20`),
|
||||
request(cfg.api.plans)
|
||||
]);
|
||||
state.ipv6 = normalizeListPayload(payload);
|
||||
state.plans = toArray(unwrap(plans));
|
||||
} else if (state.route === "system-config") {
|
||||
state.config = unwrap(await request(cfg.api.adminConfig));
|
||||
}
|
||||
@@ -337,18 +341,20 @@
|
||||
}
|
||||
|
||||
if (action === "node-copy") {
|
||||
await adminPost(`${cfg.api.adminBase}/server/manage/copy`, {
|
||||
id: Number(actionEl.getAttribute("data-id"))
|
||||
});
|
||||
const nodeId = Number(actionEl.getAttribute("data-id"));
|
||||
try {
|
||||
await adminPost(`${cfg.api.adminBase}/server/manage/copy`, { id: nodeId });
|
||||
} catch (e) { /* adminPost already shows error */ }
|
||||
await hydrateRoute();
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === "node-delete") {
|
||||
if (confirm("确认删除该节点吗?")) {
|
||||
await adminPost(`${cfg.api.adminBase}/server/manage/drop`, {
|
||||
id: Number(actionEl.getAttribute("data-id"))
|
||||
});
|
||||
const nodeId = Number(actionEl.getAttribute("data-id"));
|
||||
try {
|
||||
await adminPost(`${cfg.api.adminBase}/server/manage/drop`, { id: nodeId });
|
||||
} catch (e) { /* adminPost already shows error */ }
|
||||
await hydrateRoute();
|
||||
}
|
||||
return;
|
||||
@@ -356,15 +362,20 @@
|
||||
|
||||
if (action === "node-toggle-visible") {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const nodeId = Number(actionEl.getAttribute("data-id"));
|
||||
const input = actionEl.querySelector("input");
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
input.checked = !input.checked;
|
||||
await adminPost(`${cfg.api.adminBase}/server/manage/update`, {
|
||||
id: Number(actionEl.getAttribute("data-id")),
|
||||
show: input.checked ? 1 : 0
|
||||
});
|
||||
const newShow = !input.checked;
|
||||
input.checked = newShow;
|
||||
try {
|
||||
await adminPost(`${cfg.api.adminBase}/server/manage/update`, {
|
||||
id: nodeId,
|
||||
show: newShow ? 1 : 0
|
||||
});
|
||||
} catch (e) { /* adminPost already shows error */ }
|
||||
await hydrateRoute();
|
||||
return;
|
||||
}
|
||||
@@ -436,10 +447,20 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === "ipv6-enable") {
|
||||
if (action === "ipv6-enable-modal") {
|
||||
const userId = actionEl.getAttribute("data-user-id");
|
||||
await adminPost(`${cfg.api.ipv6Base}/enable/${userId}`, {});
|
||||
await hydrateRoute();
|
||||
const userEmail = actionEl.getAttribute("data-email") || "";
|
||||
state.modal = { type: "ipv6-enable", data: { userId, email: userEmail } };
|
||||
render();
|
||||
return;
|
||||
}
|
||||
|
||||
if (action === "ipv6-disable") {
|
||||
const userId = actionEl.getAttribute("data-user-id");
|
||||
if (confirm("确认关闭该用户的 IPv6 子账号?(软禁用,可恢复)")) {
|
||||
await adminPost(`${cfg.api.ipv6Base}/disable/${userId}`, {});
|
||||
await hydrateRoute();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -505,6 +526,14 @@
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
if (action === "ipv6-enable-save") {
|
||||
const userId = body.user_id;
|
||||
const planId = Number(body.plan_id) || 0;
|
||||
await adminPost(`${cfg.api.ipv6Base}/enable/${userId}`, { plan_id: planId });
|
||||
state.modal = null;
|
||||
await hydrateRoute();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -953,23 +982,34 @@
|
||||
}
|
||||
|
||||
function renderIPv6Manage() {
|
||||
const rows = state.ipv6.list.map((item) => [
|
||||
renderRelationChip(item.id, item.shadow_user_id || "-"),
|
||||
[
|
||||
`<strong>${escapeHtml(item.email || "-")}</strong>`,
|
||||
`<div class="subtle-text">${escapeHtml(item.ipv6_email || "-")}</div>`
|
||||
].join(""),
|
||||
escapeHtml(item.plan_name || "-"),
|
||||
renderStatus(item.status_label || item.status || "-"),
|
||||
escapeHtml(formatDate(item.updated_at)),
|
||||
renderActionRow([
|
||||
buttonAction("开通/同步", "ipv6-enable", null, `data-user-id="${item.id}"`),
|
||||
buttonAction("同步密码", "ipv6-sync-password", null, `data-user-id="${item.id}"`)
|
||||
])
|
||||
]);
|
||||
const rows = state.ipv6.list.map((item) => {
|
||||
const isActive = item.is_active || item.status === "active";
|
||||
const isDisabled = item.status === "disabled";
|
||||
const actions = [];
|
||||
if (isActive) {
|
||||
actions.push(buttonAction("关闭", "ipv6-disable", null, `data-user-id="${item.id}"`));
|
||||
actions.push(buttonAction("同步密码", "ipv6-sync-password", null, `data-user-id="${item.id}"`));
|
||||
} else {
|
||||
actions.push(buttonAction("开通", "ipv6-enable-modal", null, `data-user-id="${item.id}" data-email="${escapeHtml(item.email || "")}"`));
|
||||
}
|
||||
if (isDisabled) {
|
||||
actions.unshift(buttonAction("重新开通", "ipv6-enable-modal", null, `data-user-id="${item.id}" data-email="${escapeHtml(item.email || "")}"`));
|
||||
}
|
||||
return [
|
||||
`<code>${item.id}</code>`,
|
||||
[
|
||||
`<strong>${escapeHtml(item.email || "-")}</strong>`,
|
||||
`<div class="subtle-text">${escapeHtml(item.ipv6_email || "-")}</div>`
|
||||
].join(""),
|
||||
escapeHtml(item.plan_name || "-"),
|
||||
renderStatus(item.status_label || item.status || "-"),
|
||||
escapeHtml(formatDate(item.updated_at)),
|
||||
renderActionRow(actions)
|
||||
];
|
||||
});
|
||||
|
||||
return [
|
||||
wrapTable(["主从关系", "账号", "套餐", "状态", "更新时间", "操作"], rows),
|
||||
wrapTable(["用户ID", "账号", "IPv6 套餐", "状态", "更新时间", "操作"], rows),
|
||||
renderPagination(state.ipv6.pagination)
|
||||
].join("");
|
||||
}
|
||||
@@ -1034,7 +1074,9 @@
|
||||
? renderGroupForm(modal.data)
|
||||
: modal.type === "route"
|
||||
? renderRouteForm(modal.data)
|
||||
: "";
|
||||
: modal.type === "ipv6-enable"
|
||||
? renderIPv6EnableForm(modal.data)
|
||||
: "";
|
||||
|
||||
return [
|
||||
'<div class="modal-card">',
|
||||
@@ -1276,6 +1318,18 @@
|
||||
return `<div class="toolbar toolbar-spaced"><button class="btn btn-primary" type="submit">${escapeHtml(label)}</button></div>`;
|
||||
}
|
||||
|
||||
function renderIPv6EnableForm(data) {
|
||||
return [
|
||||
`<h2>开通 IPv6 子账号</h2>`,
|
||||
`<p>用户: <strong>${escapeHtml(data.email || data.userId)}</strong></p>`,
|
||||
'<form data-form="ipv6-enable-save">',
|
||||
hiddenField("user_id", data.userId),
|
||||
selectField("IPv6 套餐", "plan_id", state.plans, 0, true),
|
||||
submitRow("确认开通"),
|
||||
"</form>"
|
||||
].join("");
|
||||
}
|
||||
|
||||
function setBusy(value) {
|
||||
state.busy = value;
|
||||
render();
|
||||
@@ -1293,9 +1347,14 @@
|
||||
}
|
||||
|
||||
async function adminPost(url, body) {
|
||||
const response = await request(url, { method: "POST", body });
|
||||
show("操作成功", "success");
|
||||
return response;
|
||||
try {
|
||||
const response = await request(url, { method: "POST", body });
|
||||
show("操作成功", "success");
|
||||
return response;
|
||||
} catch (error) {
|
||||
show(error.message || "操作失败", "error");
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function request(url, options) {
|
||||
@@ -1382,7 +1441,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (["id", "group_id", "transfer_enable", "speed_limit", "balance", "plan_id", "device_limit", "server_port", "value"].includes(key)) {
|
||||
if (["id", "group_id", "transfer_enable", "speed_limit", "balance", "plan_id", "device_limit", "server_port", "value", "user_id"].includes(key)) {
|
||||
values[key] = rawValue === "" ? null : Number(rawValue);
|
||||
return;
|
||||
}
|
||||
@@ -1492,6 +1551,8 @@
|
||||
type = "ok";
|
||||
} else if (/(pending|warn|unverified|eligible|ready)/.test(normalized)) {
|
||||
type = "warn";
|
||||
} else if (/(disabled)/.test(normalized)) {
|
||||
type = "warn";
|
||||
}
|
||||
return `<span class="status-pill status-${type}">${escapeHtml(text)}</span>`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user