first commit

This commit is contained in:
闫旭隆
2025-10-17 09:31:28 +08:00
commit 4698145045
589 changed files with 196795 additions and 0 deletions

View File

@ -0,0 +1,480 @@
/**
* 首页认证集成 - 处理登录状态检查和用户菜单
*/
class HomeAuthIntegration {
constructor() {
this.currentUser = null;
this.isAuthenticated = false;
this.init();
}
/**
* 初始化
*/
async init() {
await this.checkAuthStatus();
this.setupEventListeners();
this.updateUI();
// 隐藏加载遮罩
const loader = document.getElementById('authCheckLoader');
if (loader) {
loader.style.display = 'none';
}
}
/**
* 检查认证状态
*/
async checkAuthStatus() {
try {
const authStatus = await AuthService.checkAuthStatus();
this.isAuthenticated = authStatus.isAuthenticated;
this.currentUser = authStatus.user;
// 如果用户已登录保存用户信息到localStorage供ChatManager使用
if (this.isAuthenticated && this.currentUser) {
localStorage.setItem('yundage_current_user', JSON.stringify(this.currentUser));
} else {
// 如果用户未登录,清除本地存储的用户信息
localStorage.removeItem('yundage_current_user');
}
console.log('Auth Status:', authStatus);
// 触发认证状态检查完成事件
window.dispatchEvent(new CustomEvent('authStatusChecked', {
detail: {
isAuthenticated: this.isAuthenticated,
user: this.currentUser
}
}));
// 路由保护逻辑
this.handleRouteProtection();
} catch (error) {
console.error('Failed to check auth status:', error);
this.isAuthenticated = false;
this.currentUser = null;
// 清除本地存储的用户信息
localStorage.removeItem('yundage_current_user');
// 即使检查失败也要触发事件
window.dispatchEvent(new CustomEvent('authStatusChecked', {
detail: {
isAuthenticated: false,
user: null,
error: error
}
}));
// 检查失败时也要处理路由保护
this.handleRouteProtection();
}
}
/**
* 处理路由保护
*/
handleRouteProtection() {
const currentPath = window.location.pathname;
const isAuthPage = currentPath.includes('/auth/pages/');
const isMainPage = currentPath.includes('/index.html') ||
currentPath === '/' ||
currentPath.endsWith('/yundage/') ||
currentPath.endsWith('/yundage');
// 如果在登录页面且已登录,跳转到首页
if (this.isAuthenticated && isAuthPage) {
console.log('已登录用户访问登录页面,跳转到首页');
setTimeout(() => {
window.location.href = '../../index.html';
}, 500);
return;
}
// 如果在主页且未登录,跳转到登录页面
if (!this.isAuthenticated && isMainPage) {
console.log('未登录用户访问主页,跳转到登录页面');
// 更新加载遮罩文字
const loader = document.getElementById('authCheckLoader');
if (loader) {
const loaderText = loader.querySelector('p');
if (loaderText) {
loaderText.textContent = '正在跳转到登录页面...';
}
}
// 显示提示
this.showNotification('请先登录', 'info');
// 短暂延迟后跳转
setTimeout(() => {
window.location.href = 'auth/pages/login.html?redirect=' + encodeURIComponent(window.location.href);
}, 500);
return;
}
}
/**
* 设置事件监听器
*/
setupEventListeners() {
// 用户菜单切换
const userMenuToggle = document.getElementById('userMenuToggle');
if (userMenuToggle) {
userMenuToggle.addEventListener('click', (e) => {
e.stopPropagation();
this.toggleUserMenu();
});
}
// 退出登录按钮
const logoutBtn = document.getElementById('logoutBtn');
if (logoutBtn) {
logoutBtn.addEventListener('click', (e) => {
e.preventDefault();
this.handleLogout();
});
}
// 点击页面其他地方关闭菜单
document.addEventListener('click', (e) => {
const userDropdown = document.getElementById('userDropdown');
const userMenuToggle = document.getElementById('userMenuToggle');
if (userDropdown && userMenuToggle) {
if (!userMenuToggle.contains(e.target) && !userDropdown.contains(e.target)) {
userDropdown.classList.add('hidden');
}
}
});
// 监听存储变化(其他标签页登录/登出)
window.addEventListener('storage', (e) => {
if (e.key === TokenManager.TOKEN_KEY || e.key === TokenManager.USER_KEY) {
this.handleStorageChange();
}
});
// 定期检查token状态
this.startTokenCheck();
}
/**
* 更新UI显示
*/
updateUI() {
const guestMenu = document.getElementById('guestMenu');
const userMenu = document.getElementById('userMenu');
const userName = document.getElementById('userName');
const userAccount = document.getElementById('userAccount');
if (this.isAuthenticated && this.currentUser) {
// 显示已登录状态
if (guestMenu) guestMenu.classList.add('hidden');
if (userMenu) userMenu.classList.remove('hidden');
// 更新用户信息显示
if (userName) {
userName.textContent = this.currentUser.username || this.currentUser.nickname || '用户';
}
if (userAccount) {
userAccount.textContent = this.currentUser.phone || this.currentUser.email || '';
}
// 更新用户头像(可选)
this.updateUserAvatar();
// 添加刷新按钮事件(如果存在)
this.setupRefreshButton();
} else {
// 显示未登录状态
if (guestMenu) guestMenu.classList.remove('hidden');
if (userMenu) userMenu.classList.add('hidden');
}
}
/**
* 设置刷新按钮
*/
setupRefreshButton() {
const refreshBtn = document.getElementById('refreshUserInfo');
if (refreshBtn && !refreshBtn._listenerAdded) {
refreshBtn._listenerAdded = true;
refreshBtn.addEventListener('click', async (e) => {
e.preventDefault();
await this.refreshUserInfo();
});
}
}
/**
* 刷新用户信息
*/
async refreshUserInfo() {
try {
console.log('手动刷新用户信息...');
const result = await AuthService.getUserInfo();
if (result.success && result.data) {
this.currentUser = result.data;
// 更新本地存储
localStorage.setItem('yundage_current_user', JSON.stringify(this.currentUser));
// 更新UI
this.updateUI();
// 显示成功提示
this.showNotification('用户信息已更新', 'success');
} else {
throw new Error(result.message || '获取用户信息失败');
}
} catch (error) {
console.error('刷新用户信息失败:', error);
// 特殊处理不同类型的错误
if (error.message.includes('403')) {
this.showNotification('没有权限访问此用户信息', 'warning');
} else if (error.message.includes('404')) {
this.showNotification('用户不存在', 'error');
} else {
this.showNotification('刷新失败:' + error.message, 'error');
}
}
}
/**
* 显示通知消息
*/
showNotification(message, type = 'info') {
// 创建通知元素
const notification = document.createElement('div');
notification.className = `fixed top-4 right-4 p-4 rounded-lg shadow-lg z-50 transition-all duration-300 transform translate-x-full`;
// 根据类型设置样式
const typeStyles = {
success: 'bg-green-500 text-white',
error: 'bg-red-500 text-white',
warning: 'bg-yellow-500 text-white',
info: 'bg-blue-500 text-white'
};
notification.className += ` ${typeStyles[type] || typeStyles.info}`;
notification.textContent = message;
// 添加到页面
document.body.appendChild(notification);
// 显示动画
setTimeout(() => {
notification.classList.remove('translate-x-full');
}, 100);
// 3秒后自动消失
setTimeout(() => {
notification.classList.add('translate-x-full');
setTimeout(() => {
notification.remove();
}, 300);
}, 3000);
}
/**
* 切换用户菜单显示
*/
toggleUserMenu() {
const userDropdown = document.getElementById('userDropdown');
if (userDropdown) {
userDropdown.classList.toggle('hidden');
}
}
/**
* 处理退出登录
*/
async handleLogout() {
try {
// 显示确认对话框
const confirmed = confirm('确定要退出登录吗?');
if (!confirmed) return;
// 执行登出
const result = await AuthService.logout();
if (result.success) {
this.isAuthenticated = false;
this.currentUser = null;
// 清除localStorage中的用户信息
localStorage.removeItem('yundage_current_user');
this.updateUI();
// 隐藏用户菜单
const userDropdown = document.getElementById('userDropdown');
if (userDropdown) {
userDropdown.classList.add('hidden');
}
// 显示成功提示
this.showNotification('已退出登录', 'success');
// 可选:刷新页面
setTimeout(() => {
window.location.reload();
}, 1000);
} else {
this.showNotification(result.message || '退出登录失败', 'error');
}
} catch (error) {
console.error('Logout error:', error);
this.showNotification('退出登录失败', 'error');
}
}
/**
* 处理存储变化(跨标签页同步)
*/
async handleStorageChange() {
await this.checkAuthStatus();
this.updateUI();
}
/**
* 更新用户头像
*/
updateUserAvatar() {
// 如果用户有头像,可以在这里更新头像显示
// 当前使用默认的太阳云朵图标
const userMenuToggle = document.getElementById('userMenuToggle');
if (userMenuToggle && this.currentUser && this.currentUser.avatar) {
// 可以在这里添加自定义头像逻辑
userMenuToggle.style.backgroundImage = `url(${this.currentUser.avatar})`;
userMenuToggle.style.backgroundSize = 'cover';
}
}
/**
* 显示通知消息
* @param {string} message - 消息内容
* @param {string} type - 消息类型success/error/info/warning
*/
showNotification(message, type = 'info') {
// 创建通知元素
const notification = document.createElement('div');
notification.className = `fixed top-20 right-4 z-50 px-4 py-3 rounded-lg shadow-lg max-w-sm transition-all duration-300 transform translate-x-full`;
// 设置样式
switch (type) {
case 'success':
notification.classList.add('bg-green-500', 'text-white');
break;
case 'error':
notification.classList.add('bg-red-500', 'text-white');
break;
case 'warning':
notification.classList.add('bg-yellow-500', 'text-white');
break;
default:
notification.classList.add('bg-blue-500', 'text-white');
}
notification.innerHTML = `
<div class="flex items-center gap-2">
<i class="fas fa-${type === 'success' ? 'check-circle' : type === 'error' ? 'exclamation-circle' : 'info-circle'}"></i>
<span>${message}</span>
<button class="ml-2 text-white hover:text-gray-200" onclick="this.parentElement.parentElement.remove()">
<i class="fas fa-times"></i>
</button>
</div>
`;
document.body.appendChild(notification);
// 显示动画
setTimeout(() => {
notification.classList.remove('translate-x-full');
}, 100);
// 自动隐藏
setTimeout(() => {
notification.classList.add('translate-x-full');
setTimeout(() => {
if (notification.parentElement) {
notification.remove();
}
}, 300);
}, 3000);
}
/**
* 开始token检查定时器
*/
startTokenCheck() {
// 每5分钟检查一次token状态
setInterval(async () => {
const isValid = TokenManager.isTokenValid();
if (this.isAuthenticated && !isValid) {
// Token已过期尝试刷新
const refreshResult = await AuthService.refreshToken();
if (!refreshResult.success) {
// 刷新失败,清除登录状态
this.isAuthenticated = false;
this.currentUser = null;
this.updateUI();
this.showNotification('登录已过期,请重新登录', 'warning');
}
}
}, 5 * 60 * 1000); // 5分钟
}
/**
* 检查是否需要登录才能使用某些功能
* @param {Function} callback - 需要登录后执行的回调函数
* @param {string} redirectUrl - 登录后的回跳地址
*/
requireAuth(callback, redirectUrl = null) {
if (this.isAuthenticated) {
callback();
} else {
// 未登录,跳转到登录页面
const loginUrl = redirectUrl
? `auth/pages/login.html?redirect=${encodeURIComponent(redirectUrl)}`
: 'auth/pages/login.html';
window.location.href = loginUrl;
}
}
/**
* 获取当前用户信息
* @returns {object|null} 用户信息
*/
getCurrentUser() {
return this.currentUser;
}
/**
* 检查是否已登录
* @returns {boolean} 是否已登录
*/
isLoggedIn() {
return this.isAuthenticated;
}
}
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
window.homeAuth = new HomeAuthIntegration();
});
// 导出供其他模块使用
if (typeof module !== 'undefined' && module.exports) {
module.exports = HomeAuthIntegration;
}