176 lines
5.9 KiB
JavaScript
176 lines
5.9 KiB
JavaScript
|
|
/**
|
|||
|
|
* 登录逻辑处理:阻止表单默认提交,校验用户名/密码,调用登录接口
|
|||
|
|
* @param {Event} e - 表单提交事件
|
|||
|
|
* @returns {boolean} - 返回false阻止默认提交
|
|||
|
|
*/
|
|||
|
|
function handleLogin(e) {
|
|||
|
|
// 1. 阻止表单默认提交行为(避免页面刷新)
|
|||
|
|
e.preventDefault();
|
|||
|
|
|
|||
|
|
// 2. 获取并清理用户名、密码(去除前后空格)
|
|||
|
|
const username = document.getElementById('username').value.trim();
|
|||
|
|
const password = document.getElementById('password').value.trim();
|
|||
|
|
|
|||
|
|
// 3. 前端简单校验(空值判断)
|
|||
|
|
if (!username) {
|
|||
|
|
showModal('请输入用户名');
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
if (!password) {
|
|||
|
|
showModal('请输入密码');
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 4. 调用后端登录接口(POST请求)
|
|||
|
|
fetch('Sys/login/userLogin', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: {
|
|||
|
|
'Content-Type': 'application/json' // 声明请求体为JSON格式
|
|||
|
|
},
|
|||
|
|
body: JSON.stringify({username, password}) // 转换为JSON字符串
|
|||
|
|
})
|
|||
|
|
.then(response => {
|
|||
|
|
// 4.1 校验HTTP响应状态(非200-299范围视为错误)
|
|||
|
|
if (!response.ok) {
|
|||
|
|
throw new Error(`请求失败,状态码:${response.status}`);
|
|||
|
|
}
|
|||
|
|
// 4.2 解析响应体(假设后端返回JSON格式)
|
|||
|
|
return response.json();
|
|||
|
|
})
|
|||
|
|
.then(data => {
|
|||
|
|
// 5. 处理后端返回结果(假设接口返回 { code: 200, msg: '成功' } 结构)
|
|||
|
|
if (data.code === 200) {
|
|||
|
|
// 登录成功:跳转到demo页面(可根据实际需求修改跳转路径)
|
|||
|
|
window.location.href = 'welcome';
|
|||
|
|
} else {
|
|||
|
|
// 业务错误:显示后端返回的错误信息,无信息时显示默认提示
|
|||
|
|
showModal(data.msg || '登录失败,请检查账号密码是否正确');
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
.catch(error => {
|
|||
|
|
// 6. 捕获请求异常(网络错误、接口500等)
|
|||
|
|
showModal(`登录异常:${error.message}`);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 显示错误弹窗
|
|||
|
|
* @param {string} msg - 弹窗提示内容
|
|||
|
|
*/
|
|||
|
|
function showModal(msg) {
|
|||
|
|
const errorMsgElem = document.getElementById('errorMsg');
|
|||
|
|
const modalElem = document.getElementById('errorModal');
|
|||
|
|
|
|||
|
|
// 设置弹窗文本内容
|
|||
|
|
errorMsgElem.innerText = msg;
|
|||
|
|
// 显示弹窗(通过flex布局实现居中)
|
|||
|
|
modalElem.style.display = 'flex';
|
|||
|
|
// 延迟添加show类(触发过渡动画,避免动画不生效)
|
|||
|
|
setTimeout(() => {
|
|||
|
|
modalElem.classList.add('show');
|
|||
|
|
}, 10);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 关闭错误弹窗
|
|||
|
|
*/
|
|||
|
|
function closeModal() {
|
|||
|
|
const modalElem = document.getElementById('errorModal');
|
|||
|
|
|
|||
|
|
// 移除show类(触发淡出动画)
|
|||
|
|
modalElem.classList.remove('show');
|
|||
|
|
// 动画结束后隐藏弹窗(300ms与CSS过渡时间保持一致)
|
|||
|
|
setTimeout(() => {
|
|||
|
|
modalElem.style.display = 'none';
|
|||
|
|
}, 300);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 清空指定输入框内容
|
|||
|
|
* @param {string} inputId - 输入框的ID属性值
|
|||
|
|
*/
|
|||
|
|
function clearInput(inputId) {
|
|||
|
|
const inputElem = document.getElementById(inputId);
|
|||
|
|
if (inputElem) {
|
|||
|
|
// 清空输入框内容
|
|||
|
|
inputElem.value = '';
|
|||
|
|
// 触发input事件(更新清空按钮的显示状态)
|
|||
|
|
inputElem.dispatchEvent(new Event('input'));
|
|||
|
|
// 聚焦到当前输入框(提升用户体验)
|
|||
|
|
inputElem.focus();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 切换密码输入框的可见性(明文/密文切换)
|
|||
|
|
*/
|
|||
|
|
function togglePasswordVisibility() {
|
|||
|
|
const passwordInput = document.getElementById('password');
|
|||
|
|
const toggleBtn = passwordInput.parentElement.querySelector('.toggle-pwd i');
|
|||
|
|
|
|||
|
|
if (passwordInput.type === 'password') {
|
|||
|
|
// 切换为明文显示
|
|||
|
|
passwordInput.type = 'text';
|
|||
|
|
// 更换图标为"眼睛"(表示当前是明文)
|
|||
|
|
toggleBtn.classList.remove('bi-eye-slash');
|
|||
|
|
toggleBtn.classList.add('bi-eye');
|
|||
|
|
} else {
|
|||
|
|
// 切换为密文显示
|
|||
|
|
passwordInput.type = 'password';
|
|||
|
|
// 更换图标为"眼睛斜杠"(表示当前是密文)
|
|||
|
|
toggleBtn.classList.remove('bi-eye');
|
|||
|
|
toggleBtn.classList.add('bi-eye-slash');
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 输入框内容变化时的动态反馈:控制清空按钮的显示/隐藏
|
|||
|
|
* @param {HTMLInputElement} inputElem - 输入框元素
|
|||
|
|
*/
|
|||
|
|
function handleInputChange(inputElem) {
|
|||
|
|
const clearBtn = inputElem.parentElement.querySelector('.clear-btn');
|
|||
|
|
if (clearBtn) {
|
|||
|
|
// 输入框有内容时显示清空按钮,无内容时隐藏
|
|||
|
|
clearBtn.hidden = !inputElem.value.trim();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 页面加载完成后:绑定全局交互事件
|
|||
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|||
|
|
// 1. 获取用户名和密码输入框元素
|
|||
|
|
const usernameInput = document.getElementById('username');
|
|||
|
|
const passwordInput = document.getElementById('password');
|
|||
|
|
|
|||
|
|
// 2. 绑定输入框内容变化事件(控制清空按钮显示)
|
|||
|
|
if (usernameInput) {
|
|||
|
|
usernameInput.addEventListener('input', () => handleInputChange(usernameInput));
|
|||
|
|
}
|
|||
|
|
if (passwordInput) {
|
|||
|
|
passwordInput.addEventListener('input', () => handleInputChange(passwordInput));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 3. 点击弹窗外部关闭弹窗
|
|||
|
|
const modalElem = document.getElementById('errorModal');
|
|||
|
|
modalElem.addEventListener('click', (e) => {
|
|||
|
|
// 仅当点击弹窗背景(而非内容区)时关闭
|
|||
|
|
if (e.target === modalElem) {
|
|||
|
|
closeModal();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 4. 按ESC键关闭弹窗
|
|||
|
|
document.addEventListener('keydown', (e) => {
|
|||
|
|
// 仅当弹窗显示时生效
|
|||
|
|
if (e.key === 'Escape' && modalElem.style.display === 'flex') {
|
|||
|
|
closeModal();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 5. 页面初始化时,默认聚焦到用户名输入框(提升用户体验)
|
|||
|
|
if (usernameInput) {
|
|||
|
|
usernameInput.focus();
|
|||
|
|
}
|
|||
|
|
});
|