/** * HTTP请求封装 * 基于uni.request进行二次封装 */ import config from '@/config/api.config.js' class Request { constructor() { this.baseURL = config.baseURL this.timeout = config.timeout } /** * 核心请求方法 * @param {Object} options 请求配置 * @returns {Promise} */ request(options) { // 显示loading if (options.loading !== false) { uni.showLoading({ title: options.loadingText || '加载中...', mask: true }) } // 打印请求信息(仅POST请求) if (options.method === 'POST') { console.log('=== HTTP POST 请求 ===') console.log('URL:', this.baseURL + options.url) console.log('Method:', options.method) console.log('请求数据:', options.data) console.log('请求头:', this.getHeaders(options.header)) } return new Promise((resolve, reject) => { uni.request({ url: this.baseURL + options.url, method: options.method || 'GET', data: options.data || {}, header: this.getHeaders(options.header), timeout: options.timeout || this.timeout, success: (res) => { // 隐藏loading if (options.loading !== false) { uni.hideLoading() } console.log('=== HTTP 响应 ===') console.log('状态码:', res.statusCode) console.log('响应数据:', res.data) // 处理响应 this.handleResponse(res, resolve, reject) }, fail: (err) => { // 隐藏loading if (options.loading !== false) { uni.hideLoading() } console.log('=== HTTP 请求失败 ===') console.log('错误信息:', err) // 处理错误 this.handleError(err, reject) } }) }) } /** * 获取请求头 * @param {Object} customHeader 自定义请求头 * @returns {Object} */ getHeaders(customHeader = {}) { // 获取token const token = uni.getStorageSync('token') || '' return { 'Content-Type': 'application/json', 'Blade-Auth': token ? `Bearer ${token}` : '', ...customHeader } } /** * 处理响应数据 * @param {Object} res 响应对象 * @param {Function} resolve Promise resolve * @param {Function} reject Promise reject */ handleResponse(res, resolve, reject) { const data = res.data // 判断HTTP状态码 // 2xx 和 304 都是成功的状态码 if (res.statusCode < 200 || (res.statusCode >= 300 && res.statusCode !== 304)) { this.showError('网络请求失败') reject({ code: res.statusCode, message: '网络请求失败' }) return } // 判断业务状态码 if (data.code === 200 || data.success === true) { // 请求成功,返回数据 resolve(data.data) } else { // 业务错误处理 const errorMsg = data.msg || data.message || '请求失败' // 特殊错误码处理 if (data.code === 401 || data.code === 403) { // token过期或无权限 this.handleTokenExpired() } this.showError(errorMsg) reject({ code: data.code, message: errorMsg, data: data.data }) } } /** * 处理请求错误 * @param {Object} err 错误对象 * @param {Function} reject Promise reject */ handleError(err, reject) { console.error('请求失败:', err) console.error('请求URL:', this.baseURL) let message = '网络请求失败' if (err.errMsg) { if (err.errMsg.includes('timeout')) { message = '请求超时,请检查网络' } else if (err.errMsg.includes('fail')) { message = '网络连接失败,请检查服务器地址' } } this.showError(message) reject({ code: undefined, message: '请求失败', data: undefined, error: err, url: this.baseURL }) } /** * 显示错误提示 * @param {String} message 错误信息 */ showError(message) { uni.showToast({ title: message, icon: 'none', duration: 2000 }) } /** * 处理token过期 */ handleTokenExpired() { // 清除token uni.removeStorageSync('token') uni.removeStorageSync('userInfo') // 提示用户 uni.showToast({ title: '登录已过期,请重新登录', icon: 'none', duration: 2000 }) // 跳转到登录页(如果有) setTimeout(() => { // uni.reLaunch({ // url: '/pages/login/login' // }) }, 2000) } /** * GET请求 * @param {String} url 请求地址 * @param {Object} data 请求参数 * @param {Object} options 额外配置 * @returns {Promise} */ get(url, data = {}, options = {}) { return this.request({ url, method: 'GET', data, ...options }) } /** * POST请求 * @param {String} url 请求地址 * @param {Object} data 请求参数 * @param {Object} options 额外配置 * @returns {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} */ put(url, data = {}, options = {}) { return this.request({ url, method: 'PUT', data, ...options }) } /** * DELETE请求 * @param {String} url 请求地址 * @param {Object} data 请求参数 * @param {Object} options 额外配置 * @returns {Promise} */ delete(url, data = {}, options = {}) { return this.request({ url, method: 'DELETE', data, ...options }) } /** * 文件上传 * @param {String} url 上传地址 * @param {String} filePath 文件路径 * @param {Object} formData 额外数据 * @returns {Promise} */ upload(url, filePath, formData = {}) { uni.showLoading({ title: '上传中...', mask: true }) return new Promise((resolve, reject) => { uni.uploadFile({ url: this.baseURL + url, filePath, name: 'file', formData, header: this.getHeaders(), success: (res) => { uni.hideLoading() const data = JSON.parse(res.data) if (data.code === 200) { resolve(data.data) } else { this.showError(data.msg || '上传失败') reject(data) } }, fail: (err) => { uni.hideLoading() this.showError('上传失败') reject(err) } }) }) } } // 导出实例 export default new Request()