(function () {
|
var userConfig = window.VISITOR_LOGIN_CONFIG || {};
|
var config = Object.assign({
|
frontendMode: "cluster",
|
deploymentMode: "cluster",
|
defaultServerIp: "",
|
apiBaseUrl: "http://localhost:9098",
|
deploymentConfigPath: "/api/deployment/config",
|
defaultBackendPort: "9098",
|
loginPath: "/api/login",
|
captchaPath: "/captchaImage",
|
title: "访客机自助登记\n管理平台"
|
}, userConfig);
|
config.frontendMode = normalizeDeploymentMode(userConfig.frontendMode || userConfig.deploymentMode || config.frontendMode);
|
config.deploymentMode = normalizeDeploymentMode(config.deploymentMode);
|
config.requireServerIp = typeof userConfig.requireServerIp === "boolean"
|
? userConfig.requireServerIp
|
: config.frontendMode === "cluster";
|
|
var loginCard = document.querySelector(".login-card");
|
var title = document.getElementById("appTitle");
|
var serverIpGroup = document.getElementById("serverIpGroup");
|
var serverIp = document.getElementById("serverIp");
|
var username = document.getElementById("username");
|
var password = document.getElementById("password");
|
var captcha = document.getElementById("captcha");
|
var captchaBox = document.getElementById("captchaBox");
|
var captchaText = document.getElementById("captchaText");
|
var captchaImage = document.getElementById("captchaImage");
|
var form = document.getElementById("loginForm");
|
var message = document.getElementById("formMessage");
|
var captchaUuid = "";
|
var captchaRequired = true;
|
|
document.title = String(config.title || "").replace(/\n/g, "");
|
title.innerHTML = String(config.title || "").replace(/\n/g, "<br>");
|
serverIp.value = config.defaultServerIp || "";
|
applyLoginMode();
|
loadBackendDeploymentConfig();
|
loadCaptchaIfReady();
|
|
captchaBox.addEventListener("click", function () {
|
loadCaptcha();
|
});
|
|
serverIp.addEventListener("blur", function () {
|
if (config.requireServerIp && isValidIpOrHost(serverIp.value.trim())) {
|
loadCaptcha();
|
}
|
});
|
|
form.addEventListener("submit", function (event) {
|
event.preventDefault();
|
setMessage("", "");
|
|
var payload = {
|
username: username.value.trim(),
|
password: password.value,
|
code: captcha.value.trim(),
|
uuid: captchaUuid
|
};
|
|
if (config.requireServerIp) {
|
payload.serverIp = serverIp.value.trim();
|
}
|
|
var error = validate(payload);
|
if (error) {
|
setMessage(error, "error");
|
return;
|
}
|
|
submitLogin(payload);
|
});
|
|
function validate(payload) {
|
if (config.requireServerIp && !isValidIpOrHost(payload.serverIp)) {
|
return "请输入正确的IP地址";
|
}
|
if (!payload.username) {
|
return "请输入用户名";
|
}
|
if (!payload.password) {
|
return "请输入密码";
|
}
|
if (captchaRequired && !captchaUuid) {
|
return "请先获取验证码";
|
}
|
if (captchaRequired && !payload.code) {
|
return "请输入验证码";
|
}
|
return "";
|
}
|
|
function applyLoginMode() {
|
serverIpGroup.hidden = !config.requireServerIp;
|
loginCard.classList.toggle("no-server-ip", !config.requireServerIp);
|
localStorage.setItem("visitor_admin_frontend_mode", config.frontendMode);
|
localStorage.setItem("visitor_admin_require_server_ip", String(config.requireServerIp));
|
}
|
|
function loadCaptchaIfReady() {
|
if (!config.requireServerIp || serverIp.value.trim()) {
|
loadCaptcha();
|
}
|
}
|
|
function loadBackendDeploymentConfig() {
|
if (!config.deploymentConfigPath) {
|
return;
|
}
|
fetch(getConfiguredApiBaseUrl() + normalizePath(config.deploymentConfigPath), {
|
method: "GET"
|
}).then(function (response) {
|
if (!response.ok) {
|
throw new Error("部署配置加载失败");
|
}
|
return response.json();
|
}).then(function (result) {
|
var data = result.data || {};
|
if (result.code !== 200 || !data) {
|
return;
|
}
|
if (data.deploymentMode) {
|
config.backendDeploymentMode = normalizeDeploymentMode(data.deploymentMode);
|
}
|
config.middlePlatformEnabled = data.middlePlatformEnabled === true;
|
localStorage.setItem("visitor_admin_backend_deployment_mode", config.backendDeploymentMode || "");
|
localStorage.setItem("visitor_admin_middle_platform_enabled", String(config.middlePlatformEnabled));
|
applyLoginMode();
|
loadCaptchaIfReady();
|
}).catch(function () {
|
applyLoginMode();
|
});
|
}
|
|
function isValidIpOrHost(value) {
|
if (!value) {
|
return false;
|
}
|
value = value.replace(/^https?:\/\//i, "");
|
var ipPattern = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}(:\d{1,5})?$/;
|
var hostPattern = /^[a-zA-Z0-9.-]+(:\d{1,5})?$/;
|
return ipPattern.test(value) || hostPattern.test(value);
|
}
|
|
function loadCaptcha() {
|
var baseUrl;
|
try {
|
baseUrl = getApiBaseUrl();
|
} catch (error) {
|
captchaText.textContent = "随机验证码区";
|
captchaImage.hidden = true;
|
captchaText.hidden = false;
|
return;
|
}
|
|
captchaText.textContent = "加载中";
|
captchaText.hidden = false;
|
captchaImage.hidden = true;
|
|
fetch(baseUrl + normalizePath(config.captchaPath), {
|
method: "GET"
|
}).then(function (response) {
|
if (!response.ok) {
|
throw new Error("验证码加载失败");
|
}
|
return response.json();
|
}).then(function (result) {
|
if (result.code !== 200) {
|
throw new Error(result.msg || "验证码加载失败");
|
}
|
captcha.value = "";
|
captchaUuid = result.uuid || "";
|
if (result.captchaEnabled === false) {
|
captchaRequired = false;
|
captchaText.textContent = "无需验证码";
|
return;
|
}
|
captchaRequired = true;
|
if (!result.img) {
|
throw new Error("验证码图片为空");
|
}
|
captchaImage.src = "data:image/jpeg;base64," + result.img;
|
captchaImage.hidden = false;
|
captchaText.hidden = true;
|
}).catch(function (error) {
|
captchaUuid = "";
|
captchaRequired = true;
|
captchaText.textContent = "点击重试";
|
captchaText.hidden = false;
|
captchaImage.hidden = true;
|
setMessage(error.message || "验证码加载失败", "error");
|
});
|
}
|
|
function submitLogin(payload) {
|
setMessage("登录中...", "");
|
fetch(getApiBaseUrl() + normalizePath(config.loginPath), {
|
method: "POST",
|
headers: {
|
"Content-Type": "application/json"
|
},
|
body: JSON.stringify(payload)
|
}).then(function (response) {
|
return response.json();
|
}).then(function (result) {
|
if (result.code !== 200) {
|
throw new Error(result.msg || "登录失败");
|
}
|
if (result.token) {
|
localStorage.setItem("visitor_admin_token", result.token);
|
}
|
localStorage.setItem("visitor_admin_api_base", getApiBaseUrl());
|
localStorage.setItem("visitor_admin_login_result", JSON.stringify(result));
|
setMessage("登录成功", "success");
|
window.setTimeout(function () {
|
window.location.href = "./pages/dashboard.html";
|
}, 300);
|
}).catch(function (error) {
|
setMessage(error.message || "登录失败", "error");
|
loadCaptcha();
|
});
|
}
|
|
function setMessage(text, type) {
|
message.textContent = text;
|
message.classList.toggle("success", type === "success");
|
if (!text || !window.AppMessage) {
|
return;
|
}
|
if (type === "success") {
|
AppMessage.success("操作成功");
|
} else if (type === "error") {
|
AppMessage.error("操作失败:" + text);
|
}
|
}
|
|
function getApiBaseUrl() {
|
if (!config.requireServerIp) {
|
return getConfiguredApiBaseUrl();
|
}
|
return normalizeServerIp(serverIp.value.trim());
|
}
|
|
function getConfiguredApiBaseUrl() {
|
return trimRightSlash(config.apiBaseUrl || window.location.origin);
|
}
|
|
function normalizeServerIp(value) {
|
if (!isValidIpOrHost(value)) {
|
throw new Error("请输入正确的IP地址");
|
}
|
var result = value;
|
if (!/^https?:\/\//i.test(result)) {
|
result = "http://" + result;
|
}
|
var url = new URL(result);
|
if (!url.port && config.defaultBackendPort) {
|
url.port = config.defaultBackendPort;
|
}
|
return trimRightSlash(url.origin);
|
}
|
|
function normalizePath(path) {
|
return "/" + String(path || "").replace(/^\/+/, "");
|
}
|
|
function trimRightSlash(value) {
|
return String(value || "").replace(/\/+$/, "");
|
}
|
|
function normalizeDeploymentMode(value) {
|
return String(value || "").toLowerCase() === "cluster" ? "cluster" : "standalone";
|
}
|
})();
|