(function () {
var config = Object.assign({
apiBaseUrl: "http://localhost:9098"
}, window.VISITOR_LOGIN_CONFIG || {});
var state = {
rows: [],
total: 0,
pageNum: 1,
pageSize: 10
};
init();
function init() {
if (!getToken()) {
redirectToLogin();
return;
}
bindLayoutActions();
bindPageActions();
applyUserInfo(readLoginUser());
loadProfileName();
loadRoles();
}
function bindLayoutActions() {
var userMenuButton = document.getElementById("userMenuButton");
var userDropdown = document.getElementById("userDropdown");
var fullscreenButton = document.querySelector(".icon-button");
userMenuButton.addEventListener("click", function (event) {
event.stopPropagation();
var hidden = userDropdown.hidden;
userDropdown.hidden = !hidden;
userMenuButton.setAttribute("aria-expanded", String(hidden));
});
userDropdown.addEventListener("click", function (event) {
var action = event.target.getAttribute("data-action");
if (!action) {
return;
}
userDropdown.hidden = true;
userMenuButton.setAttribute("aria-expanded", "false");
if (action === "home") {
window.location.href = "./dashboard.html";
} else if (action === "logout") {
logout();
}
});
document.addEventListener("click", function () {
userDropdown.hidden = true;
userMenuButton.setAttribute("aria-expanded", "false");
});
fullscreenButton.addEventListener("click", function () {
if (!document.fullscreenElement && document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
} else if (document.exitFullscreen) {
document.exitFullscreen();
}
});
}
function bindPageActions() {
document.getElementById("queryForm").addEventListener("submit", function (event) {
event.preventDefault();
state.pageNum = 1;
loadRoles();
});
document.getElementById("resetButton").addEventListener("click", function () {
document.getElementById("queryForm").reset();
state.pageNum = 1;
loadRoles();
});
document.getElementById("addRoleButton").addEventListener("click", function () {
window.location.href = "./role-form.html?mode=add";
});
}
function loadProfileName() {
apiRequest("/system/user/profile", { method: "GET" }).then(function (result) {
applyUserInfo(result.data || {});
}).catch(function () {
applyUserInfo(readLoginUser());
});
}
function loadRoles() {
apiRequest("/system/role/manage/page", {
method: "POST",
body: JSON.stringify({
pageNum: state.pageNum,
pageSize: state.pageSize,
roleName: document.getElementById("queryRoleName").value.trim()
})
}).then(function (result) {
var data = result.data || {};
state.rows = data.records || data.list || [];
state.total = Number(data.total || state.rows.length || 0);
state.pageNum = Number(data.current || data.pageNum || state.pageNum);
state.pageSize = Number(data.size || data.pageSize || state.pageSize);
renderTable();
renderPagination();
}).catch(function (error) {
state.rows = [];
state.total = 0;
renderTable();
renderPagination();
AppMessage.error("操作失败:" + (error.message || "角色加载失败"));
});
}
function renderTable() {
var body = document.getElementById("roleTableBody");
var empty = document.getElementById("roleEmpty");
empty.hidden = state.rows.length > 0;
body.innerHTML = state.rows.map(function (item, index) {
var rowNumber = (state.pageNum - 1) * state.pageSize + index + 1;
var userCount = Number(item.userCount || 0);
var deleteDisabled = Number(item.roleId) === 1;
return [
"
",
"| " + rowNumber + " | ",
"" + escapeHtml(item.roleName || "-") + " | ",
"" + userCount + " | ",
"" + escapeHtml(formatDateTime(item.createTime)) + " | ",
"" + escapeHtml(item.remark || "-") + " | ",
"",
"",
"",
"",
" | ",
"
"
].join("");
}).join("");
body.querySelectorAll("[data-action]").forEach(function (button) {
button.addEventListener("click", function () {
var id = Number(button.getAttribute("data-id"));
var action = button.getAttribute("data-action");
if (action === "detail") {
window.location.href = "./role-form.html?mode=detail&roleId=" + id;
} else if (action === "edit") {
window.location.href = "./role-form.html?mode=edit&roleId=" + id;
} else if (action === "delete") {
deleteRole(id);
}
});
});
}
function deleteRole(roleId) {
AppConfirm.open({
title: "是否确认删除数据?",
message: "仅未绑定账号情况下可删除权限组。",
onConfirm: function () {
return apiRequest("/system/role/manage/delete", {
method: "POST",
body: JSON.stringify({ roleIds: [roleId] })
}).then(function () {
AppMessage.success("操作成功");
loadRoles();
});
}
});
}
function renderPagination() {
var root = document.getElementById("pagination");
var totalPage = Math.max(1, Math.ceil(state.total / state.pageSize));
var pages = [];
for (var page = 1; page <= Math.min(totalPage, 5); page++) {
pages.push('');
}
if (totalPage > 5) {
pages.push("...");
}
root.innerHTML = [
"共 " + state.total + " 条",
"每页 条",
pages.join(""),
"前往 页"
].join("");
document.getElementById("pageSizeSelect").value = String(state.pageSize);
root.querySelectorAll("[data-page]").forEach(function (button) {
button.addEventListener("click", function () {
state.pageNum = Number(button.getAttribute("data-page"));
loadRoles();
});
});
document.getElementById("pageSizeSelect").addEventListener("change", function (event) {
state.pageSize = Number(event.target.value);
state.pageNum = 1;
loadRoles();
});
document.getElementById("jumpPageInput").addEventListener("keydown", function (event) {
if (event.key === "Enter") {
state.pageNum = Math.min(totalPage, Math.max(1, Number(event.target.value) || 1));
loadRoles();
}
});
}
function apiRequest(path, options) {
options = options || {};
var headers = options.headers || {};
var token = getToken();
if (token) {
headers.Authorization = "Bearer " + token;
}
if (!options.skipJson) {
headers["Content-Type"] = "application/json";
}
return fetch(getApiBaseUrl() + normalizePath(path), {
method: options.method || "GET",
headers: headers,
body: options.body
}).then(function (response) {
return response.json().catch(function () {
return { code: response.ok ? 200 : response.status, msg: response.statusText };
});
}).then(function (result) {
if (result.code === 401) {
clearLoginState();
redirectToLogin();
throw new Error(result.msg || "登录状态已过期");
}
if (result.code !== 200) {
throw new Error(result.msg || "请求失败");
}
return result;
});
}
function logout() {
apiRequest("/logout", {
method: "POST",
skipJson: true
}).catch(function () {
return null;
}).then(function () {
clearLoginState();
redirectToLogin();
});
}
function applyUserInfo(user) {
user = user || {};
var displayName = user.nickName || user.userName || user.username || "用户";
document.getElementById("userDisplayName").textContent = displayName;
document.querySelector(".user-avatar").textContent = displayName.substring(0, 1);
}
function readLoginUser() {
try {
var loginResult = JSON.parse(localStorage.getItem("visitor_admin_login_result") || "{}");
return (loginResult.userInfo && loginResult.userInfo.user) || loginResult.user || {};
} catch (error) {
return {};
}
}
function formatDateTime(value) {
return value ? String(value).slice(0, 19).replace("T", " ") : "-";
}
function getApiBaseUrl() {
return trimRightSlash(localStorage.getItem("visitor_admin_api_base") || config.apiBaseUrl || window.location.origin);
}
function getToken() {
return localStorage.getItem("visitor_admin_token") || "";
}
function clearLoginState() {
localStorage.removeItem("visitor_admin_token");
localStorage.removeItem("visitor_admin_login_result");
localStorage.removeItem("visitor_admin_api_base");
}
function redirectToLogin() {
window.location.href = "../index.html";
}
function normalizePath(path) {
return "/" + String(path || "").replace(/^\/+/, "");
}
function trimRightSlash(value) {
return String(value || "").replace(/\/+$/, "");
}
function escapeHtml(value) {
return String(value == null ? "" : value).replace(/[&<>"']/g, function (char) {
return {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
}[char];
});
}
})();