/** * 给 request uploadFile 添加拦截器 * * 1. 基础地址 * 2. 超时时间 * 3. 请求头 * 4. token */ import { useMemberStore } from '@/stores/modules/member' const baseUrl = 'https://pcapi-xiaotuxian-front-devtest.itheima.net' // 拦截器配置 const interceptorOptions = { // 拦截前触发 invoke(options: UniApp.RequestOptions) { // 1. baseUrl if (!options.url.startsWith('http')) { options.url = baseUrl + options.url } // 2. 超时时间, 默认60s options.timeout = 60 * 1000 // 3. 请求头 options.header = { ...options.header, 'source-client': 'miniapp', } // 4. token const token = useMemberStore().profile?.token if (token) { options.header.Authorization = token } }, } uni.addInterceptor('request', interceptorOptions) uni.addInterceptor('uploadFile', interceptorOptions) /** * 请求函数 * @param UniApp.RequestOptions * @returns Promise * 1. 返回 Promise 对象 * 2. 获取数据成功 * 2.1 提取核心数据 res.data * 2.2 添加类型,支持泛型 * 3. 获取数据失败 * 3.1 401错误 -> 清理用户信息,跳转到登录页 * 3.2 其他错误 -> 根据后端错误信息轻提示 * 3.3 网络错误 -> 提示用户换网络 */ type Data = { code: string msg: string result: T } export const http = (options: UniApp.RequestOptions) => { return new Promise>((resolve, reject) => { uni.request({ ...options, // 1. 响应成功 success: (res) => { if (res.statusCode >= 200 && res.statusCode < 300) { // 2xx 成功, 提取核心数据 res.data resolve(res.data as Data) return } if (res.statusCode === 401) { // 401错误 -> 清理用户信息,跳转到登录页 useMemberStore().clearProfile() uni.navigateTo({ url: '/pages/login/login', }) reject(res.data as Data) return } // 其他错误 -> 根据后端错误信息轻提示 uni.showToast({ title: (res.data as Data).msg || '请求失败', icon: 'none', }) reject(res.data as Data) }, // 2. 响应失败 fail: (err) => { reject(err.errMsg) uni.showToast({ title: '网络错误,请稍后再试', icon: 'none', }) }, }) }) }