import { useUserStore } from '../stores/user' import { getToken } from './storage' const BASE_URL = import.meta.env.VITE_SYSTEM_URL // 防止多个 401 同时触发登出和跳转 let isHandling401 = false /** * 网络请求封装 * @param {Object} options 请求参数 * @returns {Promise} */ const request = options => { // 默认配置 const defaultOptions = { url: '', method: 'GET', data: {}, header: { deviceId: uni.getDeviceInfo().deviceId, 'Content-Type': 'application/json' // 默认请求内容类型 } } // 合并配置 const config = { ...defaultOptions, ...options } // 请求拦截:添加token等通用header if (getToken()) { config.header['Authorization'] = 'Bearer ' + getToken() } // 显示加载状态(可选) if (options.loading !== false) { uni.showLoading({ title: '加载中...', mask: true }) } return new Promise((resolve, reject) => { uni.request({ url: BASE_URL + config.url, method: config.method, data: config.data, timeout: 10000, // 请求超时时间 header: config.header, success: response => { // 响应拦截:根据状态码处理 if (response.statusCode === 200) { // 这里可以根据后端数据格式调整 // 例如:if (response.data.code === 0) {...} if (response.data.code === 200) { resolve(response.data) } else { // 注意:这里也要 reject,否则调用方无法感知失败 const err = handleError(response.data.code, response.data) reject(err || response.data) // handleError(response.data.code, response.data) } } else { // 状态码错误处理 // handleError(response.statusCode, response.data) // reject(response) const err = handleError(response.statusCode, response.data) reject(err || response) } }, fail: error => { // 网络错误处理 uni.showToast({ title: '网络异常,请检查网络连接', icon: 'none', duration: 2000, mask: true }) reject(error) }, complete: () => { // 隐藏加载状态 if (options.loading !== false) { uni.hideLoading() } } }) }) } /** * 错误处理函数 * @param {Number} statusCode HTTP状态码 * @param {Object} data 响应数据 */ const handleError = (statusCode, data) => { // 如果是 401 且正在处理中,直接返回(避免重复处理) if (statusCode === 401) { if (isHandling401) { return new Error('Unauthorized') } isHandling401 = true uni.showModal({ title: '提示', content: '登录已过期,请重新登录', showCancel: false, success: async () => { await useUserStore().clearAllUserInfo() // 可选:跳转登录页 uni.reLaunch({ url: '/pages/login/login' }) console.log('登录已过期,====') }, complete: () => { // 重置标志,允许下次 401 处理(比如用户重新登录后再次过期) isHandling401 = false } }) return new Error('Unauthorized') } switch (statusCode) { // case 401: // console.log('登录已过期,====') // uni.showModal({ // title: '提示', // content: '登录已过期,请重新登录', // showCancel: false, // success: () => { // useUserStore().logout() // // uni.navigateTo({ // // url: '/pages/login/index' // // }) // } // }) // break case 403: uni.showToast({ title: '没有权限访问', icon: 'none', duration: 2000, mask: true }) break case 404: uni.showToast({ title: '请求资源不存在', icon: 'none', duration: 2000, mask: true }) break case 500: uni.showModal({ title: `${statusCode}提示`, content: data.msg || '服务器内部错误', showCancel: false, confirmText: '确定' }) // uni.showToast({ // title: data.msg || '服务器内部错误', // icon: 'none', // duration: 2000, // mask: true // }) break default: uni.showToast({ title: data.msg || '请求失败,请重试', icon: 'none', duration: 2000, mask: true }) } return new Error(`Request failed with code: ${statusCode}`) } export default request