(function () {
|
var config = Object.assign({
|
apiBaseUrl: "http://localhost:9098"
|
}, window.VISITOR_LOGIN_CONFIG || {});
|
|
var PROTOCOL_TYPE = "ENTRY_COMMITMENT";
|
var PROTOCOL_NAME = "入园承诺";
|
var editor = document.getElementById("protocolEditor");
|
var editorShell = document.getElementById("editorShell");
|
|
init();
|
|
function init() {
|
if (!getToken()) {
|
redirectToLogin();
|
return;
|
}
|
bindLayoutActions();
|
bindEditorActions();
|
bindFormActions();
|
applyUserInfo(readLoginUser());
|
loadProfileName();
|
loadProtocol();
|
}
|
|
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 bindEditorActions() {
|
document.querySelectorAll(".editor-toolbar button").forEach(function (button) {
|
button.addEventListener("click", function () {
|
if (button.id === "editorFullscreen") {
|
editorShell.classList.toggle("fullscreen");
|
editor.focus();
|
return;
|
}
|
runEditorCommand(button.getAttribute("data-command"), button.getAttribute("data-value"));
|
});
|
});
|
|
editor.addEventListener("paste", function (event) {
|
event.preventDefault();
|
var html = event.clipboardData.getData("text/html");
|
var text = event.clipboardData.getData("text/plain");
|
insertHtml(html ? sanitizeHtml(html) : escapeHtml(text).replace(/\n/g, "<br>"));
|
});
|
|
document.addEventListener("keydown", function (event) {
|
if (event.key === "Escape" && editorShell.classList.contains("fullscreen")) {
|
editorShell.classList.remove("fullscreen");
|
}
|
});
|
}
|
|
function bindFormActions() {
|
document.getElementById("protocolForm").addEventListener("submit", function (event) {
|
event.preventDefault();
|
saveProtocol();
|
});
|
}
|
|
function runEditorCommand(command, value) {
|
editor.focus();
|
document.execCommand(command, false, value || null);
|
}
|
|
function insertHtml(html) {
|
editor.focus();
|
document.execCommand("insertHTML", false, html);
|
}
|
|
function loadProfileName() {
|
apiRequest("/system/user/profile", { method: "GET" }).then(function (result) {
|
applyUserInfo(result.data || {});
|
}).catch(function () {
|
applyUserInfo(readLoginUser());
|
});
|
}
|
|
function loadProtocol() {
|
apiRequest("/system/protocol/config/detail", {
|
method: "POST",
|
body: JSON.stringify({ protocolType: PROTOCOL_TYPE })
|
}).then(function (result) {
|
var data = result.data || {};
|
editor.innerHTML = sanitizeHtml(data.protocolContent || "");
|
}).catch(function (error) {
|
editor.innerHTML = "";
|
AppMessage.error("操作失败:" + (error.message || "入园承诺加载失败"));
|
});
|
}
|
|
function saveProtocol() {
|
var saveButton = document.getElementById("saveProtocolButton");
|
var content = sanitizeHtml(editor.innerHTML || "").trim();
|
if (!content || !editor.textContent.trim()) {
|
AppMessage.error("操作失败:请输入入园承诺内容");
|
return;
|
}
|
|
saveButton.disabled = true;
|
apiRequest("/system/protocol/config/save", {
|
method: "POST",
|
body: JSON.stringify({
|
protocolType: PROTOCOL_TYPE,
|
protocolName: PROTOCOL_NAME,
|
protocolContent: content,
|
enabled: true
|
})
|
}).then(function (result) {
|
var data = result.data || {};
|
editor.innerHTML = sanitizeHtml(data.protocolContent || content);
|
AppMessage.success("操作成功");
|
}).catch(function (error) {
|
AppMessage.error("操作失败:" + (error.message || "入园承诺保存失败"));
|
}).then(function () {
|
saveButton.disabled = false;
|
});
|
}
|
|
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 sanitizeHtml(html) {
|
var template = document.createElement("template");
|
template.innerHTML = String(html || "");
|
template.content.querySelectorAll("script, style, iframe, object, embed, link, meta").forEach(function (node) {
|
node.parentNode.removeChild(node);
|
});
|
template.content.querySelectorAll("*").forEach(function (node) {
|
Array.prototype.slice.call(node.attributes).forEach(function (attribute) {
|
var name = attribute.name.toLowerCase();
|
var value = attribute.value || "";
|
if (name.indexOf("on") === 0 || /javascript:/i.test(value)) {
|
node.removeAttribute(attribute.name);
|
}
|
});
|
});
|
return template.innerHTML;
|
}
|
|
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];
|
});
|
}
|
})();
|