Files
web_huangguo_web/app/static/js/pages/loginDialog.js
T
fish03andClaude Opus 5.5 bef9f8b4ed Initial commit
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 14:43:16 +07:00

237 lines
7.9 KiB
JavaScript

(function () {
var mask = document.getElementById("loginDialog");
if (!mask) return;
var form = mask.querySelector("[data-login-dialog-form]");
var accountInput = mask.querySelector("[data-login-account]");
var passwordInput = mask.querySelector("[data-login-password]");
var submitBtn = mask.querySelector("[data-login-submit]");
var defaultSubmitText = (submitBtn && submitBtn.textContent) || "登录";
function setSubmitting(loading) {
if (!submitBtn) return;
submitBtn.disabled = !!loading;
submitBtn.classList.toggle("is-loading", !!loading);
submitBtn.setAttribute("aria-busy", loading ? "true" : "false");
submitBtn.textContent = loading ? "登录中..." : defaultSubmitText;
}
function getField(name) {
return mask.querySelector('[data-login-field="' + name + '"]');
}
function setFieldError(name, message) {
var field = getField(name);
if (!field) return;
var control = field.querySelector("[data-login-control]");
var error = field.querySelector("[data-login-error]");
if (control) control.classList.add("is-error");
if (error) {
error.textContent = message;
error.hidden = false;
}
}
function clearFieldError(name) {
var field = getField(name);
if (!field) return;
var control = field.querySelector("[data-login-control]");
var error = field.querySelector("[data-login-error]");
if (control) control.classList.remove("is-error");
if (error) error.hidden = true;
}
function clearAllErrors() {
clearFieldError("account");
clearFieldError("password");
}
function isValidLength(value) {
return value.length >= 4 && value.length <= 16;
}
function validateForm() {
var account = (accountInput && accountInput.value.trim()) || "";
var password = (passwordInput && passwordInput.value) || "";
var valid = true;
clearAllErrors();
if (!account) {
setFieldError("account", "账号格式不正确,请输入有效账号");
valid = false;
} else if (!window.AuthAPI || !AuthAPI.isValidLoginAccount(account)) {
setFieldError("account", "账号格式不正确,请输入有效账号");
valid = false;
}
if (!password) {
setFieldError("password", "密码错误,请检查后重新输入");
valid = false;
} else if (!isValidLength(password)) {
setFieldError("password", "密码错误,请检查后重新输入");
valid = false;
}
if (!valid) return null;
return { account: account, password: password };
}
function mapServerError(err) {
var tip = (err && err.message) || "登录失败,请稍后重试";
if (/密码|password/i.test(tip)) {
setFieldError("password", tip);
return;
}
if (/账号|账户|用户|邮箱|account|email|不存在|错误/i.test(tip)) {
setFieldError("account", tip);
return;
}
if (window.AuthAPI) AuthAPI.toast(tip, "error");
else if (typeof showToast === "function") showToast(tip, "error");
}
function openDialog(event) {
if (event) event.preventDefault();
if (typeof window.closeRegisterDialog === "function") {
window.closeRegisterDialog();
}
clearAllErrors();
mask.classList.add("is-open");
document.body.style.overflow = "hidden";
return true;
}
function closeDialog() {
mask.classList.remove("is-open");
clearAllErrors();
if (!document.getElementById("registerDialog") || !document.getElementById("registerDialog").classList.contains("is-open")) {
document.body.style.overflow = "";
}
}
function setLoginErrors(errors) {
clearAllErrors();
if (!errors) return;
if (errors.account) setFieldError("account", errors.account);
if (errors.password) setFieldError("password", errors.password);
}
if (form) {
form.addEventListener("submit", function (event) {
event.preventDefault();
if (submitBtn && submitBtn.classList.contains("is-loading")) return;
var payload = validateForm();
if (!payload) return;
if (!window.AuthAPI || !window.HttpRequest) {
return;
}
setSubmitting(true);
AuthAPI.login(payload)
.then(function () {
AuthAPI.toast("登录成功", "success");
closeDialog();
setTimeout(function () {
goAfterAuth();
}, 400);
})
.catch(function (err) {
setSubmitting(false);
mapServerError(err);
});
});
}
function isSafeRedirect(path) {
return typeof path === "string" && path.charAt(0) === "/" && path.charAt(1) !== "/";
}
function goAfterAuth() {
var bodyRedirect = document.body && document.body.getAttribute("data-auth-redirect");
if (isSafeRedirect(bodyRedirect)) {
window.location.href = bodyRedirect;
return;
}
var params = new URLSearchParams(window.location.search);
var redirect = params.get("redirect");
if (isSafeRedirect(redirect)) {
window.location.href = redirect;
return;
}
window.location.reload();
}
function consumeAuthQuery(kind) {
var params = new URLSearchParams(window.location.search);
if (params.get("auth") !== kind) return false;
params.delete("auth");
var qs = params.toString();
var next = window.location.pathname + (qs ? "?" + qs : "") + window.location.hash;
window.history.replaceState(null, "", next);
return true;
}
if (accountInput) {
accountInput.addEventListener("input", function () {
clearFieldError("account");
});
}
if (passwordInput) {
passwordInput.addEventListener("input", function () {
clearFieldError("password");
});
}
document.addEventListener("click", function (event) {
var openEl = event.target.closest("[data-login-dialog-open]");
if (openEl) {
openDialog(event);
return;
}
var loginLink = event.target.closest('a[href="/login/"], a[href="#login"]');
if (loginLink) {
openDialog(event);
return;
}
if (event.target.closest("[data-login-dialog-close]")) {
closeDialog();
return;
}
if (event.target.closest("[data-login-dialog-eye]")) {
var btn = event.target.closest("[data-login-dialog-eye]");
var input = document.getElementById("loginDialogPassword");
var img = btn.querySelector("img");
if (!input || !img) return;
var show = input.type === "password";
input.type = show ? "text" : "password";
img.src = show ? "/static/images/eye_open.svg" : "/static/images/eye_close.svg";
btn.setAttribute("aria-label", show ? "隐藏密码" : "显示密码");
return;
}
if (event.target === mask) {
closeDialog();
}
});
document.addEventListener("keydown", function (event) {
if (event.key === "Escape" && mask.classList.contains("is-open")) {
closeDialog();
}
});
window.openLoginDialog = openDialog;
window.closeLoginDialog = closeDialog;
window.setLoginDialogErrors = setLoginErrors;
if ((document.body && document.body.getAttribute("data-auth-mode") === "login") || consumeAuthQuery("login")) {
openDialog();
}
})();