import { authApi } from './auth'; // 设置token到localStorage export const setToken = (token: string) => { if (typeof window !== 'undefined') { localStorage.setItem('token', token); } }; // 获取token export const getToken = (): string | null => { if (typeof window !== 'undefined') { return localStorage.getItem('token'); } return null; }; // 清除token export const clearToken = () => { if (typeof window !== 'undefined') { localStorage.removeItem('token'); localStorage.removeItem('userInfo'); localStorage.removeItem('token_expired'); localStorage.removeItem('s2_accountId'); } }; // 验证token是否有效 export const validateToken = async (): Promise => { try { const response = await authApi.getUserInfo(); return response.code === 200; } catch (error) { console.error('Token验证失败:', error); return false; } }; // 刷新令牌 export const refreshAuthToken = async (): Promise => { if (typeof window === 'undefined') { return false; } try { const response = await authApi.refreshToken(); if (response.code === 200 && response.data?.token) { setToken(response.data.token); // 更新过期时间 if (response.data.token_expired) { localStorage.setItem('token_expired', response.data.token_expired); } return true; } return false; } catch (error) { console.error('刷新Token失败:', error); return false; } }; // 检查token是否即将过期 export const isTokenExpiringSoon = (): boolean => { if (typeof window === 'undefined') { return false; } const tokenExpired = localStorage.getItem('token_expired'); if (!tokenExpired) return true; try { const expiredTime = new Date(tokenExpired).getTime(); const currentTime = new Date().getTime(); // 提前10分钟认为即将过期 return currentTime >= (expiredTime - 10 * 60 * 1000); } catch (error) { console.error('解析token过期时间失败:', error); return true; } }; // 检查token是否已过期 export const isTokenExpired = (): boolean => { if (typeof window === 'undefined') { return false; } const tokenExpired = localStorage.getItem('token_expired'); if (!tokenExpired) return true; try { const expiredTime = new Date(tokenExpired).getTime(); const currentTime = new Date().getTime(); // 提前5分钟认为过期,给刷新留出时间 return currentTime >= (expiredTime - 5 * 60 * 1000); } catch (error) { console.error('解析token过期时间失败:', error); return true; } }; // 请求去重器 class RequestDeduplicator { private pendingRequests = new Map>(); async deduplicate(key: string, requestFn: () => Promise): Promise { if (this.pendingRequests.has(key)) { return this.pendingRequests.get(key)!; } const promise = requestFn(); this.pendingRequests.set(key, promise); try { const result = await promise; return result; } finally { this.pendingRequests.delete(key); } } getPendingCount(): number { return this.pendingRequests.size; } clear(): void { this.pendingRequests.clear(); } } // 请求取消管理器 class RequestCancelManager { private abortControllers = new Map(); createController(key: string): AbortController { // 取消之前的请求 this.cancelRequest(key); const controller = new AbortController(); this.abortControllers.set(key, controller); return controller; } cancelRequest(key: string): void { const controller = this.abortControllers.get(key); if (controller) { controller.abort(); this.abortControllers.delete(key); } } cancelAllRequests(): void { this.abortControllers.forEach(controller => controller.abort()); this.abortControllers.clear(); } getController(key: string): AbortController | undefined { return this.abortControllers.get(key); } } // 导出单例实例 export const requestDeduplicator = new RequestDeduplicator(); export const requestCancelManager = new RequestCancelManager(); /** * 通用文件上传方法(支持图片、文件) * @param {File} file - 要上传的文件对象 * @param {string} [uploadUrl='/v1/attachment/upload'] - 上传接口地址 * @returns {Promise} - 上传成功后返回文件url */ export async function uploadFile(file: File, uploadUrl: string = '/v1/attachment/upload'): Promise { const formData = new FormData(); formData.append('file', file); const token = typeof window !== 'undefined' ? localStorage.getItem('token') : ''; const headers: Record = {}; if (token) headers['Authorization'] = `Bearer ${token}`; try { const response = await fetch(uploadUrl, { method: 'POST', headers, body: formData, }); const res = await response.json(); if (res?.url) { return res.url; } if (res?.data?.url) { return res.data.url; } throw new Error(res?.msg || '文件上传失败'); } catch (e: any) { throw new Error(e?.message || '文件上传失败'); } }