/** * 统一请求拦截器 */ import { userStore } from '@/store/index.js'; // 基础配置 const BASE_CONFIG = { timeout: 30000, // 30秒超时 header: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' } }; /** * 创建请求实例 */ class HttpRequest { constructor() { this.config = { ...BASE_CONFIG }; } /** * 响应拦截器 - 处理Cookie和错误 * @param {Object} response 响应对象 * @returns {Promise} 处理后的响应 */ async interceptResponse(response) { try { if (response.data.system_result_message_key) { uni.showToast({ title: response.data.system_result_message_key + ",请重新登录", icon: 'none' }); // 等待 logout 操作完成 await userStore.actions.logout(); setTimeout(() => { uni.navigateTo({ url: '/pages/login/login' }); }, 500); } // 检查HTTP状态码 if (response.statusCode >= 200 && response.statusCode < 300) { // 检查业务状态码 if (response.data && typeof response.data === 'object') { if (response.data.code === '0' || response.data.code === 0 || response.data.code === 200) { // 业务成功 return response.data; } else { // 业务失败 const error = new Error(response.data.message || response.data.msg || '请求失败'); error.code = response.data.code; error.data = response.data; throw error; } } else { // 非JSON响应,直接返回 return response.data; } } else { // HTTP状态码错误 const error = new Error( `HTTP ${response.statusCode}: ${this.getStatusText(response.statusCode)}` ); error.statusCode = response.statusCode; error.response = response; throw error; } } catch (error) { console.error('响应拦截器错误:', error); throw error; } } /** * 获取状态码描述 * @param {number} statusCode HTTP状态码 * @returns {string} 状态描述 */ getStatusText(statusCode) { const statusMap = { 400: 'Bad Request', 401: 'Unauthorized', 403: 'Forbidden', 404: 'Not Found', 500: 'Internal Server Error', 502: 'Bad Gateway', 503: 'Service Unavailable' }; return statusMap[statusCode] || 'Unknown Error'; } /** * 通用请求方法 * @param {Object} options 请求选项 * @returns {Promise} 请求Promise */ request(options) { return new Promise((resolve, reject) => { // 合并配置,特别处理 header const config = { ...this.config, ...options, header: { ...this.config.header, ...(options.header || options.headers || {}) }, withCredentials: false }; // 发起请求 uni.request({ ...config, success: (response) => { this.interceptResponse(response) .then(resolve) .catch(reject); }, fail: (error) => { console.error('请求失败:', error); const err = new Error(error.errMsg || '网络请求失败'); err.error = error; reject(err); } }); }); } /** * GET请求 * @param {string} url 请求地址 * @param {Object} params 查询参数 * @param {Object} options 其他选项 * @returns {Promise} 请求Promise */ get(url, params = {}, options = {}) { // 构建查询字符串 const queryString = Object.keys(params) .filter(key => params[key] !== undefined && params[key] !== null) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`) .join('&'); const finalUrl = queryString ? `${url}${url.includes('?') ? '&' : '?'}${queryString}` : url; return this.request({ url: finalUrl, method: 'GET', ...options }); } /** * POST请求 * @param {string} url 请求地址 * @param {Object} data 请求体数据 * @param {Object} options 其他选项 * @returns {Promise} 请求Promise */ post(url, data = {}, options = {}) { return this.request({ url, method: 'POST', data, ...options }); } /** * PUT请求 * @param {string} url 请求地址 * @param {Object} data 请求体数据 * @param {Object} options 其他选项 * @returns {Promise} 请求Promise */ put(url, data = {}, options = {}) { return this.request({ url, method: 'PUT', data, ...options }); } /** * DELETE请求 * @param {string} url 请求地址 * @param {Object} params 查询参数 * @param {Object} options 其他选项 * @returns {Promise} 请求Promise */ delete(url, params = {}, options = {}) { return this.get(url, params, { ...options, method: 'DELETE' }); } } // 创建请求实例 const httpRequest = new HttpRequest(); export default httpRequest; // 导出常用方法 export const { get, post, put, delete: del } = httpRequest;