const KEY_TOKEN = 'COMPREHENSIVE_VENUE_TOKEN' const API_BASE_URL = import.meta.env.VITE_COMPREHENSIVE_API_BASE_URL || 'http://127.0.0.1:8001' let pendingToken = null const normalizeError = (res, fallbackMessage = '请求服务失败') => { const body = res?.data || res || {} return { code: body.code || res?.statusCode || 50000, message: body.message || fallbackMessage, errors: body.errors || null, statusCode: res?.statusCode } } export const authStorage = { setToken(token) { uni.setStorageSync(KEY_TOKEN, token) }, getToken() { return uni.getStorageSync(KEY_TOKEN) }, setPendingToken(token) { pendingToken = token }, getPendingToken() { return pendingToken }, clearPendingToken() { pendingToken = null }, clear() { uni.removeStorageSync(KEY_TOKEN) pendingToken = null }, isLoggedIn() { return !!uni.getStorageSync(KEY_TOKEN) } } let isRedirecting = false function redirectToLogin() { if (isRedirecting) return const pages = getCurrentPages() const current = pages[pages.length - 1] const currentRoute = current?.route || '' if (currentRoute === 'pages/comprehensive/profile/login' || currentRoute === 'pages/comprehensive/profile/setup') { return } isRedirecting = true authStorage.clear() uni.reLaunch({ url: '/pages/comprehensive/profile/login', complete: () => { isRedirecting = false } }) } export function request(options = {}) { const token = authStorage.getToken() || authStorage.getPendingToken() const header = { 'Content-Type': 'application/json', ...(options.header || {}) } if (token) { header.Authorization = `Bearer ${token}` } return new Promise((resolve, reject) => { uni.request({ url: options.url.startsWith('http') ? options.url : `${API_BASE_URL}${options.url}`, method: options.method || 'GET', data: options.data, header, success: (res) => { const body = res.data if (res.statusCode === 401 || body?.code === 40001) { redirectToLogin() reject(normalizeError(res, '')) return } if (res.statusCode >= 200 && res.statusCode < 300 && body?.code === 0) { resolve(body.data) return } const error = normalizeError(res, `请求错误 ${res.statusCode}`) uni.showToast({ title: error.message, icon: 'none' }) reject(error) }, fail: (err) => { const error = normalizeError(err, '网络连接失败,请检查服务') uni.showToast({ title: error.message, icon: 'none' }) reject(error) } }) }) } export function uploadFile(options = {}) { const token = authStorage.getToken() || authStorage.getPendingToken() const header = { ...(options.header || {}) } if (token) { header.Authorization = `Bearer ${token}` } return new Promise((resolve, reject) => { uni.uploadFile({ url: options.url.startsWith('http') ? options.url : `${API_BASE_URL}${options.url}`, filePath: options.filePath, name: options.name || 'file', formData: options.formData || {}, header, success: (res) => { let body = {} try { body = JSON.parse(res.data || '{}') } catch (error) { body = {} } if (res.statusCode === 401 || body?.code === 40001) { redirectToLogin() reject(normalizeError({ ...res, data: body }, '')) return } if (res.statusCode >= 200 && res.statusCode < 300 && body?.code === 0) { resolve(body.data) return } const uploadError = normalizeError({ ...res, data: body }, `上传错误 ${res.statusCode}`) uni.showToast({ title: uploadError.message, icon: 'none' }) reject(uploadError) }, fail: (err) => { const uploadError = normalizeError(err, '文件上传失败,请检查服务') uni.showToast({ title: uploadError.message, icon: 'none' }) reject(uploadError) } }) }) }