138 lines
4.5 KiB
JavaScript
138 lines
4.5 KiB
JavaScript
(function () {
|
||
var form = document.querySelector("[data-login-page-form]");
|
||
var password = document.querySelector("[data-login-page-password]");
|
||
var toggle = document.querySelector("[data-login-page-toggle]");
|
||
var toggleIcon = document.querySelector("[data-login-page-toggle-icon]");
|
||
var submitBtn = document.querySelector("[data-login-page-submit]") || (form && form.querySelector('button[type="submit"]'));
|
||
var root = form || document;
|
||
|
||
if (toggle && password && toggleIcon) {
|
||
toggle.addEventListener("click", function () {
|
||
var show = password.getAttribute("type") === "password";
|
||
password.setAttribute("type", show ? "text" : "password");
|
||
toggleIcon.setAttribute("src", show ? "/static/images/eye-off.svg" : "/static/images/eye.svg");
|
||
toggle.setAttribute("aria-label", show ? "隐藏密码" : "显示密码");
|
||
});
|
||
}
|
||
|
||
function clearFieldError(name) {
|
||
var field = root.querySelector('[data-field="' + name + '"]');
|
||
var err = root.querySelector('[data-field-error="' + name + '"]');
|
||
if (field) field.classList.remove("is-error");
|
||
if (err) {
|
||
err.hidden = true;
|
||
var text = err.querySelector("[data-field-error-text]");
|
||
if (text) text.textContent = "";
|
||
}
|
||
}
|
||
|
||
function clearAllErrors() {
|
||
root.querySelectorAll("[data-field]").forEach(function (el) {
|
||
el.classList.remove("is-error");
|
||
});
|
||
root.querySelectorAll("[data-field-error]").forEach(function (err) {
|
||
err.hidden = true;
|
||
var text = err.querySelector("[data-field-error-text]");
|
||
if (text) text.textContent = "";
|
||
});
|
||
}
|
||
|
||
function setFieldError(name, message) {
|
||
var field = root.querySelector('[data-field="' + name + '"]');
|
||
var err = root.querySelector('[data-field-error="' + name + '"]');
|
||
if (field) field.classList.add("is-error");
|
||
if (err) {
|
||
err.hidden = false;
|
||
var text = err.querySelector("[data-field-error-text]");
|
||
if (text) text.textContent = message || "";
|
||
}
|
||
}
|
||
|
||
function isLen4to16(value) {
|
||
var len = String(value || "").length;
|
||
return len >= 4 && len <= 16;
|
||
}
|
||
|
||
function validateForm() {
|
||
clearAllErrors();
|
||
var fd = new FormData(form);
|
||
var account = String(fd.get("account") || "").trim();
|
||
var pwd = String(fd.get("password") || "");
|
||
var valid = true;
|
||
|
||
if (!account) {
|
||
setFieldError("account", "请输入账号");
|
||
valid = false;
|
||
} else if (
|
||
!(window.AuthAPI && AuthAPI.isValidLoginAccount
|
||
? AuthAPI.isValidLoginAccount(account)
|
||
: isLen4to16(account) || account.indexOf("@") >= 0)
|
||
) {
|
||
setFieldError("account", "账号需为 4–16 位,或合法邮箱");
|
||
valid = false;
|
||
}
|
||
|
||
if (!pwd) {
|
||
setFieldError("password", "请输入密码");
|
||
valid = false;
|
||
} else if (!isLen4to16(pwd)) {
|
||
setFieldError("password", "密码需为 4–16 位");
|
||
valid = false;
|
||
}
|
||
|
||
if (!valid) return null;
|
||
return { account: account, password: pwd };
|
||
}
|
||
|
||
function mapServerError(err) {
|
||
var tip = (err && err.message) || "登录失败,请稍后重试";
|
||
if (/账号|账户|用户|不存在|邮箱/.test(tip) && !/密码/.test(tip)) {
|
||
setFieldError("account", tip);
|
||
return;
|
||
}
|
||
setFieldError("password", tip);
|
||
}
|
||
|
||
function setSubmitting(loading) {
|
||
if (!submitBtn) return;
|
||
submitBtn.disabled = !!loading;
|
||
submitBtn.classList.toggle("is-loading", !!loading);
|
||
submitBtn.textContent = loading ? "登录中…" : "登录";
|
||
}
|
||
|
||
if (form) {
|
||
form.querySelectorAll("input").forEach(function (input) {
|
||
input.addEventListener("input", function () {
|
||
var name = input.getAttribute("name");
|
||
if (name) clearFieldError(name);
|
||
});
|
||
});
|
||
|
||
form.addEventListener("submit", function (event) {
|
||
event.preventDefault();
|
||
if (!window.AuthAPI || !window.HttpRequest) {
|
||
setFieldError("password", "认证脚本未加载,请刷新页面");
|
||
return;
|
||
}
|
||
if (submitBtn && submitBtn.classList.contains("is-loading")) return;
|
||
|
||
var payload = validateForm();
|
||
if (!payload) return;
|
||
|
||
setSubmitting(true);
|
||
AuthAPI.login(payload)
|
||
.then(function (res) {
|
||
AuthAPI.toast((res && res.tip) || "登录成功", "success");
|
||
window.setTimeout(function () {
|
||
window.location.href = "/";
|
||
}, 400);
|
||
})
|
||
.catch(function (err) {
|
||
setSubmitting(false);
|
||
mapServerError(err);
|
||
AuthAPI.toast((err && err.message) || "登录失败", "error");
|
||
});
|
||
});
|
||
}
|
||
})();
|