caddydash/frontend/js/init.js
wjqserver b10790c212 init
2025-06-20 16:33:27 +08:00

150 lines
No EOL
5.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// js/init.js
document.addEventListener('DOMContentLoaded', () => {
const DOMElements = {
initForm: document.getElementById('init-form'),
initButton: null,
toastContainer: document.getElementById('toast-container'),
usernameInput: document.getElementById('username'),
passwordInput: document.getElementById('password'),
confirmPasswordInput: document.getElementById('confirm_password'),
};
const INIT_API_URL = '/v0/api/auth/init';
const PASSWORD_MIN_LENGTH = 8;
const TOAST_DEFAULT_DURATION = 3000;
const REDIRECT_DELAY_SUCCESS = 1500;
const theme = {
init: () => {
const storedTheme = localStorage.getItem('theme');
const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const currentTheme = storedTheme || (systemPrefersDark ? 'dark' : 'light');
document.documentElement.dataset.theme = currentTheme;
}
};
const toast = {
_container: null,
_icons: { success: 'fa-check-circle', error: 'fa-times-circle', info: 'fa-info-circle' },
init: (containerElement) => {
if (!containerElement) {
console.error('Toast container element not found.');
return;
}
toast._container = containerElement;
toast._container.addEventListener('click', (e) => {
if (e.target.dataset.toastClose !== undefined) {
toast._hideToast(e.target.closest('.toast'));
}
});
},
show: (message, type = 'info', duration = TOAST_DEFAULT_DURATION) => {
if (!toast._container) {
console.error('Toast module not initialized. Container is missing.');
return;
}
const iconClass = toast._icons[type] || 'fa-info-circle';
const toastElement = document.createElement('div');
toastElement.className = `toast ${type}`;
toastElement.innerHTML = `
<i class="toast-icon fa-solid ${iconClass}"></i>
<p class="toast-message">${message}</p>
<button class="toast-close" data-toast-close>×</button>
`;
toast._container.appendChild(toastElement);
requestAnimationFrame(() => toastElement.classList.add('show'));
setTimeout(() => toast._hideToast(toastElement), duration);
},
_hideToast: (toastElement) => {
if (!toastElement) return;
toastElement.classList.remove('show');
toastElement.addEventListener('transitionend', () => toastElement.remove(), { once: true });
}
};
async function handleInitSubmit(e) {
e.preventDefault();
// 1. 获取并修剪输入值
const username = DOMElements.usernameInput.value.trim(); // 获取用户名并去除前后空格
const password = DOMElements.passwordInput.value.trim();
const confirmPassword = DOMElements.confirmPasswordInput.value.trim();
// 2. 添加用户名输入框的空值验证
if (username === '') {
toast.show('管理员用户名不能为空', 'error');
DOMElements.usernameInput.focus();
return;
}
// 其他密码验证逻辑不变
if (password === '') {
toast.show('密码不能为空', 'error');
DOMElements.passwordInput.focus();
return;
}
if (confirmPassword === '') {
toast.show('确认密码不能为空', 'error');
DOMElements.confirmPasswordInput.focus();
return;
}
if (password !== confirmPassword) {
toast.show('两次输入的密码不匹配', 'error');
DOMElements.passwordInput.focus();
return;
}
if (password.length < PASSWORD_MIN_LENGTH) {
toast.show(`密码长度至少为 ${PASSWORD_MIN_LENGTH}`, 'error');
DOMElements.passwordInput.focus();
return;
}
DOMElements.initButton.disabled = true;
DOMElements.initButton.querySelector('span').textContent = '设置中...';
try {
const formData = new FormData(DOMElements.initForm);
formData.set('username', username); // 确保发送的是修剪过的用户名
formData.set('password', password); // 确保发送的是修剪过的密码
formData.delete('confirm_password');
const response = await fetch(INIT_API_URL, {
method: 'POST',
body: new URLSearchParams(formData)
});
const result = await response.json();
if (response.ok) {
toast.show('管理员账户创建成功!正在跳转到登录页面...', 'success');
setTimeout(() => { window.location.href = '/login.html'; }, REDIRECT_DELAY_SUCCESS);
} else {
throw new Error(result.error || `初始化失败: ${response.status}`);
}
} catch (error) {
toast.show(error.message, 'error');
DOMElements.initButton.disabled = false;
DOMElements.initButton.querySelector('span').textContent = '完成设置';
}
}
function initApp() {
theme.init();
if (DOMElements.initForm) {
DOMElements.initButton = DOMElements.initForm.querySelector('button[type="submit"]');
toast.init(DOMElements.toastContainer);
DOMElements.initForm.addEventListener('submit', handleInitSubmit);
} else {
console.error('Init form element not found. Script may not function correctly.');
}
}
initApp();
});