/** * API服务工具 * 统一处理网络请求、错误处理、token管理等 */ const app = getApp(); // API配置 const API_CONFIG = { baseUrl: 'https://api.xiaozhi.com', // 生产环境API地址 timeout: 10000, retryCount: 3, retryDelay: 1000 }; // 请求状态码 const STATUS_CODE = { SUCCESS: 200, UNAUTHORIZED: 401, FORBIDDEN: 403, NOT_FOUND: 404, SERVER_ERROR: 500, NETWORK_ERROR: -1 }; // 错误消息映射 const ERROR_MESSAGES = { [STATUS_CODE.UNAUTHORIZED]: '登录已过期,请重新登录', [STATUS_CODE.FORBIDDEN]: '没有访问权限', [STATUS_CODE.NOT_FOUND]: '请求的资源不存在', [STATUS_CODE.SERVER_ERROR]: '服务器内部错误', [STATUS_CODE.NETWORK_ERROR]: '网络连接失败,请检查网络设置' }; /** * 基础请求方法 * @param {Object} options 请求配置 * @returns {Promise} 请求结果 */ function request(options) { return new Promise((resolve, reject) => { const { url, method = 'GET', data = {}, header = {}, needAuth = true, showLoading = true, loadingText = '加载中...', retryCount = 0 } = options; // 显示加载提示 if (showLoading) { wx.showLoading({ title: loadingText, mask: true }); } // 构建请求头 const requestHeader = { 'Content-Type': 'application/json', ...header }; // 添加认证token if (needAuth && app.globalData.token) { requestHeader['Authorization'] = `Bearer ${app.globalData.token}`; } // 发起请求 wx.request({ url: `${API_CONFIG.baseUrl}${url}`, method, data, header: requestHeader, timeout: API_CONFIG.timeout, success: (res) => { if (showLoading) { wx.hideLoading(); } const { statusCode, data: responseData } = res; // 请求成功 if (statusCode === STATUS_CODE.SUCCESS) { if (responseData.code === 0) { resolve(responseData); } else { // 业务错误 handleBusinessError(responseData, reject); } } else { // HTTP错误 handleHttpError(statusCode, reject, options, retryCount); } }, fail: (error) => { if (showLoading) { wx.hideLoading(); } console.error('Request failed:', error); // 网络错误重试 if (retryCount < API_CONFIG.retryCount) { setTimeout(() => { request({ ...options, retryCount: retryCount + 1 }).then(resolve).catch(reject); }, API_CONFIG.retryDelay); } else { handleNetworkError(error, reject); } } }); }); } /** * 处理业务错误 * @param {Object} responseData 响应数据 * @param {Function} reject 拒绝函数 */ function handleBusinessError(responseData, reject) { const { code, message } = responseData; // 特殊错误码处理 switch (code) { case 401: // token过期,清除登录状态 app.clearLoginStatus(); wx.showToast({ title: '登录已过期', icon: 'none' }); // 跳转到登录页 wx.navigateTo({ url: '/pages/login/login' }); break; case 403: wx.showToast({ title: '权限不足', icon: 'none' }); break; default: wx.showToast({ title: message || '操作失败', icon: 'none' }); } reject({ code, message, type: 'business' }); } /** * 处理HTTP错误 * @param {Number} statusCode 状态码 * @param {Function} reject 拒绝函数 * @param {Object} options 请求选项 * @param {Number} retryCount 重试次数 */ function handleHttpError(statusCode, reject, options, retryCount) { const message = ERROR_MESSAGES[statusCode] || '请求失败'; // 401错误特殊处理 if (statusCode === STATUS_CODE.UNAUTHORIZED) { app.clearLoginStatus(); wx.navigateTo({ url: '/pages/login/login' }); } // 5xx错误重试 if (statusCode >= 500 && retryCount < API_CONFIG.retryCount) { setTimeout(() => { request({ ...options, retryCount: retryCount + 1 }).then(resolve).catch(reject); }, API_CONFIG.retryDelay); return; } wx.showToast({ title: message, icon: 'none' }); reject({ code: statusCode, message, type: 'http' }); } /** * 处理网络错误 * @param {Object} error 错误对象 * @param {Function} reject 拒绝函数 */ function handleNetworkError(error, reject) { wx.showToast({ title: '网络连接失败', icon: 'none' }); reject({ code: STATUS_CODE.NETWORK_ERROR, message: '网络连接失败', type: 'network', error }); } /** * GET请求 * @param {String} url 请求地址 * @param {Object} params 请求参数 * @param {Object} options 其他选项 * @returns {Promise} 请求结果 */ function get(url, params = {}, options = {}) { const queryString = Object.keys(params) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`) .join('&'); const requestUrl = queryString ? `${url}?${queryString}` : url; return request({ url: requestUrl, method: 'GET', ...options }); } /** * POST请求 * @param {String} url 请求地址 * @param {Object} data 请求数据 * @param {Object} options 其他选项 * @returns {Promise} 请求结果 */ function post(url, data = {}, options = {}) { return request({ url, method: 'POST', data, ...options }); } /** * PUT请求 * @param {String} url 请求地址 * @param {Object} data 请求数据 * @param {Object} options 其他选项 * @returns {Promise} 请求结果 */ function put(url, data = {}, options = {}) { return request({ url, method: 'PUT', data, ...options }); } /** * DELETE请求 * @param {String} url 请求地址 * @param {Object} options 其他选项 * @returns {Promise} 请求结果 */ function del(url, options = {}) { return request({ url, method: 'DELETE', ...options }); } /** * 文件上传 * @param {String} url 上传地址 * @param {String} filePath 文件路径 * @param {Object} formData 表单数据 * @param {Object} options 其他选项 * @returns {Promise} 上传结果 */ function upload(url, filePath, formData = {}, options = {}) { return new Promise((resolve, reject) => { const { name = 'file', header = {}, needAuth = true, showLoading = true } = options; if (showLoading) { wx.showLoading({ title: '上传中...', mask: true }); } // 构建请求头 const requestHeader = { ...header }; if (needAuth && app.globalData.token) { requestHeader['Authorization'] = `Bearer ${app.globalData.token}`; } wx.uploadFile({ url: `${API_CONFIG.baseUrl}${url}`, filePath, name, formData, header: requestHeader, success: (res) => { if (showLoading) { wx.hideLoading(); } try { const data = JSON.parse(res.data); if (data.code === 0) { resolve(data); } else { handleBusinessError(data, reject); } } catch (error) { reject({ code: -1, message: '响应数据解析失败', type: 'parse', error }); } }, fail: (error) => { if (showLoading) { wx.hideLoading(); } handleNetworkError(error, reject); } }); }); } // 会员相关API const memberAPI = { // 获取用户信息 getUserInfo() { return get('/api/member/user/info'); }, // 微信登录 wxLogin(code) { return post('/api/member/auth/wx-login', { code }, { needAuth: false }); }, // 获取会员信息 getMemberInfo() { return get('/api/member/info'); }, // 绑定会员 bindMember(memberData) { return post('/api/member/bind', memberData); }, // 解绑会员 unbindMember() { return post('/api/member/unbind'); }, // 获取会员权益 getMemberBenefits() { return get('/api/member/benefits'); }, // 验证会员权益 verifyBenefit(benefitType) { return post('/api/member/verify-benefit', { benefitType }); }, // 获取会员等级配置 getMemberLevels() { return get('/api/member/levels'); }, // 升级会员 upgradeMember(targetLevel) { return post('/api/member/upgrade', { targetLevel }); }, // 获取绑定历史 getBindHistory(page = 1, size = 10) { return get('/api/member/bind-history', { page, size }); }, // 获取权益使用记录 getBenefitUsage(page = 1, size = 10) { return get('/api/member/benefit-usage', { page, size }); }, // 邀请好友 inviteFriend(inviteCode) { return post('/api/member/invite', { inviteCode }); }, // 获取邀请记录 getInviteHistory(page = 1, size = 10) { return get('/api/member/invite-history', { page, size }); } }; // 支付相关API const paymentAPI = { // 创建支付订单 createOrder(orderData) { return post('/api/payment/create-order', orderData); }, // 查询订单状态 queryOrder(orderId) { return get(`/api/payment/order/${orderId}`); }, // 取消订单 cancelOrder(orderId) { return post(`/api/payment/order/${orderId}/cancel`); }, // 申请退款 requestRefund(orderId, refundData) { return post(`/api/payment/order/${orderId}/refund`, refundData); }, // 查询退款状态 queryRefund(refundId) { return get(`/api/payment/refund/${refundId}`); } }; // 通用API const commonAPI = { // 获取系统配置 getSystemConfig() { return get('/api/common/config', {}, { needAuth: false }); }, // 上传图片 uploadImage(filePath) { return upload('/api/common/upload/image', filePath); }, // 发送验证码 sendVerifyCode(phone) { return post('/api/common/send-verify-code', { phone }, { needAuth: false }); }, // 验证验证码 verifyCode(phone, code) { return post('/api/common/verify-code', { phone, code }, { needAuth: false }); } }; module.exports = { request, get, post, put, del: del, upload, memberAPI, paymentAPI, commonAPI, API_CONFIG, STATUS_CODE };