(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, "
")); }); 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]; }); } })();