Files
all-in-one-sys/js/utils/auth-helper.js
KQL 61698639ef feat: 完成多多畅职就业服务平台核心功能开发
主要更新:
-  完成主题配色从暗色到亮蓝白配色的全面转换
-  实现高薪岗位页面及后端API集成
-  完成登录注册页面及认证系统
-  实现预招录确认功能
-  添加数据库管理和维护工具脚本
-  优化错误处理和用户体验

核心功能:
1. 首页 (index.html) - 3D地球、专业分类、过渡岗位
2. 高薪岗位页面 (high.html) - 岗位详情、预招录确认、成功案例
3. 登录注册 (auth.html) - 用户认证、专业分类选择
4. 后端API - RESTful接口,JWT认证,MySQL数据库

技术栈:
- 前端:Three.js, GSAP, 原生JavaScript
- 后端:Node.js, Express, MySQL
- 认证:JWT, bcrypt
- 样式:自定义CSS,响应式设计

数据库工具:
- kill-by-ids.js - 批量终止MySQL进程
- unlock-all-tables.js - 解锁数据库表
- init-db.js - 初始化数据库
- 其他管理脚本

🤖 Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 15:40:55 +08:00

221 lines
6.0 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.

/**
* 认证工具模块
* 用于其他页面检查登录状态、获取用户信息、退出登录等
*/
const AuthHelper = {
// 配置常量
TOKEN_KEY: 'duoduo_auth_token',
USER_INFO_KEY: 'duoduo_user_info',
API_BASE_URL: 'http://192.168.1.17:8080/api',
/**
* 获取存储的token
* @returns {string|null} token字符串或null
*/
getToken() {
return localStorage.getItem(this.TOKEN_KEY);
},
/**
* 获取存储的用户信息
* @returns {Object|null} 用户信息对象或null
*/
getUserInfo() {
const userInfo = localStorage.getItem(this.USER_INFO_KEY);
return userInfo ? JSON.parse(userInfo) : null;
},
/**
* 检查是否已登录
* @returns {boolean} 是否已登录
*/
isLoggedIn() {
return !!this.getToken();
},
/**
* 退出登录
* 清除所有认证信息并跳转到登录页
*/
logout() {
localStorage.removeItem(this.TOKEN_KEY);
localStorage.removeItem(this.USER_INFO_KEY);
window.location.href = 'auth.html';
},
/**
* 验证token是否有效
* 调用后端API验证token如果无效则清除登录状态
* @returns {Promise<boolean>} token是否有效
*/
async validateToken() {
const token = this.getToken();
if (!token) {
return false;
}
try {
const response = await fetch(`${this.API_BASE_URL}/auth/me`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
const data = await response.json();
if (data.success) {
// 更新用户信息
localStorage.setItem(this.USER_INFO_KEY, JSON.stringify(data.data));
return true;
}
}
// Token无效清除登录状态
this.logout();
return false;
} catch (error) {
console.error('Token验证失败:', error);
return false;
}
},
/**
* 路由守卫:保护需要登录的页面
* 如果未登录则跳转到登录页
* @param {string} redirectUrl 跳转的登录页URL默认为auth.html
* @returns {boolean} 是否已登录
*/
requireAuth(redirectUrl = 'auth.html') {
if (!this.isLoggedIn()) {
window.location.href = redirectUrl;
return false;
}
return true;
},
/**
* 获取带认证头的fetch配置
* @param {Object} options fetch的配置对象
* @returns {Object} 包含Authorization头的配置对象
*/
getAuthHeaders(options = {}) {
const token = this.getToken();
return {
...options,
headers: {
...options.headers,
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
};
},
/**
* 发送认证请求的封装方法
* @param {string} url 请求URL
* @param {Object} options fetch配置
* @returns {Promise<Object>} 响应数据
*/
async fetchWithAuth(url, options = {}) {
const response = await fetch(url, this.getAuthHeaders(options));
// 如果返回401未授权清除登录状态并跳转
if (response.status === 401) {
this.logout();
return null;
}
return response.json();
},
/**
* 获取当前用户信息(从服务器获取最新)
* @returns {Promise<Object|null>} 用户信息或null
*/
async getCurrentUser() {
try {
const data = await this.fetchWithAuth(`${this.API_BASE_URL}/auth/me`);
if (data && data.success) {
// 更新本地存储的用户信息
localStorage.setItem(this.USER_INFO_KEY, JSON.stringify(data.data));
return data.data;
}
return null;
} catch (error) {
console.error('获取用户信息失败:', error);
return null;
}
},
/**
* 更新用户资料
* @param {Object} profileData 要更新的资料数据
* @returns {Promise<boolean>} 是否更新成功
*/
async updateProfile(profileData) {
try {
const data = await this.fetchWithAuth(`${this.API_BASE_URL}/auth/profile`, {
method: 'PUT',
body: JSON.stringify(profileData)
});
if (data && data.success) {
// 更新成功后刷新用户信息
await this.getCurrentUser();
return true;
}
return false;
} catch (error) {
console.error('更新资料失败:', error);
return false;
}
},
/**
* 在页面中显示用户名
* @param {string} elementId 要显示用户名的元素ID
*/
displayUsername(elementId) {
const userInfo = this.getUserInfo();
if (userInfo && userInfo.username) {
const element = document.getElementById(elementId);
if (element) {
element.textContent = userInfo.username;
}
}
},
/**
* 在页面中显示用户完整信息
* @param {Object} elementIds 元素ID映射对象 {username: 'username-el', email: 'email-el', ...}
*/
displayUserInfo(elementIds) {
const userInfo = this.getUserInfo();
if (!userInfo) return;
for (const [field, elementId] of Object.entries(elementIds)) {
const element = document.getElementById(elementId);
if (element && userInfo[field]) {
element.textContent = userInfo[field];
}
}
}
};
// 如果在浏览器环境中,暴露到全局
if (typeof window !== 'undefined') {
window.AuthHelper = AuthHelper;
}
// 支持ES6模块导出
if (typeof module !== 'undefined' && module.exports) {
module.exports = AuthHelper;
}