/** * PerToolBox Front - 公共 JavaScript */ // ========== 全局变量 ========== let currentUser = null; // ========== 工具函数 ========== function getToken() { return localStorage.getItem('token'); } function setToken(token) { if (token) { localStorage.setItem('token', token); } else { localStorage.removeItem('token'); } } function isLoggedIn() { return !!getToken(); } // ========== API 请求封装 ========== async function apiRequest(endpoint, options = {}) { const baseUrl = window.API_BASE || '/api/v1'; const url = endpoint.startsWith('http') ? endpoint : `${baseUrl}${endpoint}`; // 默认 headers const headers = { ...options.headers }; // 如果没有设置 Content-Type 且 body 是 URLSearchParams,不自动添加 if (!options.headers || !options.headers['Content-Type']) { if (options.body && options.body instanceof URLSearchParams) { // 表单数据,不添加 JSON Content-Type headers['Content-Type'] = 'application/x-www-form-urlencoded'; } else if (options.body && typeof options.body === 'string') { // 已经是字符串,不添加 } else if (options.body && typeof options.body === 'object') { // JSON 对象 headers['Content-Type'] = 'application/json'; options.body = JSON.stringify(options.body); } } const token = getToken(); if (token) { headers['Authorization'] = `Bearer ${token}`; } try { const response = await fetch(url, { ...options, headers }); if (response.status === 401) { setToken(null); if (!window.location.pathname.includes('/login.php')) { window.location.href = '/login.php'; } return null; } // 获取响应文本 const text = await response.text(); if (!response.ok) { let errorMsg; try { const errorData = JSON.parse(text); errorMsg = errorData.detail || errorData.message || JSON.stringify(errorData); } catch (e) { errorMsg = text || '请求失败'; } throw new Error(errorMsg); } try { return JSON.parse(text); } catch (e) { return text; } } catch (error) { console.error('API 请求错误:', error); throw error; } } // ========== 热度上报 ========== async function recordUsage(toolName) { try { await apiRequest(`/tool/usage?tool_name=${toolName}`, { method: 'POST' }); console.log(`✅ 热度上报: ${toolName}`); } catch (error) { console.warn('热度上报失败:', error); } } // ========== 获取用户信息 ========== async function loadUserInfo() { if (!isLoggedIn()) { updateUserUI(null); return null; } try { const user = await apiRequest('/user/profile'); currentUser = user; updateUserUI(user); return user; } catch (error) { console.error('获取用户信息失败:', error); setToken(null); updateUserUI(null); return null; } } // ========== 更新侧边栏 UI ========== function updateUserUI(user) { const userInfoDiv = document.getElementById('userInfo'); const profileLink = document.getElementById('profileLink'); const logoutBtn = document.getElementById('logoutBtn'); const loginLink = document.getElementById('loginLink'); if (user) { const displayName = user.username || user.phone || user.email || '用户'; if (userInfoDiv) { userInfoDiv.innerHTML = `