import { env } from '../config/env' import { pinia } from '../store' const AUTH_REQUIRED_CODE = 40101 const AUTH_EXPIRED_CODE = 40102 const TOKEN_KEY = 'ULTHON_ADMIN_TOKEN' function buildUrl(url) { if (!url) return '' if (/^https?:\/\//i.test(url)) return url const baseUrl = env.apiBaseUrl || '' if (url.startsWith('/')) return `${baseUrl}${url}` return `${baseUrl}/${url}` } function getCurrentRoutePath() { try { const pages = getCurrentPages() const current = pages && pages[pages.length - 1] const route = (current && (current.route || (current.$page && current.$page.fullPath))) || '' return String(route) } catch (e) { return '' } } function redirectToLoginIfNeeded() { const route = getCurrentRoutePath() if (route.includes('pages/login/index')) return uni.navigateTo({ url: '/pages/login/index', fail: () => { uni.reLaunch({ url: '/pages/login/index' }) }, }) } async function getUserStoreSafely() { try { const mod = await import('../store/user') if (!mod || typeof mod.useUserStore !== 'function') return null const userStore = mod.useUserStore(pinia) if (userStore && typeof userStore.init === 'function') { userStore.init() } return userStore || null } catch (e) { return null } } function getTokenFromStorage() { try { return uni.getStorageSync(TOKEN_KEY) || '' } catch (e) { return '' } } function clearTokenFromStorage() { try { uni.removeStorageSync(TOKEN_KEY) } catch (e) { } } async function handleAuthFailed() { const userStore = await getUserStoreSafely() if (userStore && typeof userStore.logout === 'function') { userStore.logout() } else { clearTokenFromStorage() } redirectToLoginIfNeeded() } export async function request(options) { const url = buildUrl(options.url) const method = (options.method || 'GET').toUpperCase() const header = { Accept: 'application/json', ...(options.header || {}), } const silent = !!options.silent const token = (options && options.token) || getTokenFromStorage() if (token && !header.Authorization) { header.Authorization = `Bearer ${token}` } if (!header['content-type'] && method !== 'GET') { header['content-type'] = 'application/x-www-form-urlencoded' } return new Promise((resolve, reject) => { uni.request({ url, method, data: options.data || {}, header, timeout: options.timeout || env.timeout || 60000, success: (res) => { const resData = res.data if (!res || typeof res !== 'object') { if (!silent) uni.showToast({ title: '请求失败', icon: 'none' }) reject(new Error('Invalid response')) return } if (res.statusCode && res.statusCode >= 400) { if (!silent) uni.showToast({ title: `请求错误(${res.statusCode})`, icon: 'none' }) reject(new Error(`HTTP ${res.statusCode}`)) return } if (resData && typeof resData === 'object' && 'code' in resData) { if (resData.code === 0) { resolve(resData) return } if (resData.code === AUTH_REQUIRED_CODE || resData.code === AUTH_EXPIRED_CODE) { void handleAuthFailed() } if (!silent) uni.showToast({ title: resData.msg || '请求失败', icon: 'none' }) reject(resData) return } resolve(resData) }, fail: (err) => { if (!silent) uni.showToast({ title: '网络异常', icon: 'none' }) reject(err) }, }) }) }