// api.js - 适配uView3+uni-app版本 // 基础配置 const BASE_URL = 'http://192.168.1.55:5001/api' const TIMEOUT = 10000 // 初始化时设置token const token = uni.getStorageSync('token') const commonHeaders = { 'Content-Type': 'application/json' } if (token) { commonHeaders['Authorization'] = `Bearer ${token}` } // 请求队列,用于管理loading let requestQueue = 0 let loadingTimer = null // 显示加载动画 const showLoading = () => { requestQueue++ if (loadingTimer) { clearTimeout(loadingTimer) loadingTimer = null } loadingTimer = setTimeout(() => { if (requestQueue > 0) { uni.showLoading({ title: '加载中...', mask: true }) } }, 300) } // 隐藏加载动画 const hideLoading = () => { requestQueue-- if (requestQueue <= 0) { requestQueue = 0 if (loadingTimer) { clearTimeout(loadingTimer) loadingTimer = null } uni.hideLoading() } } // 核心请求函数 const request = (config) => { return new Promise((resolve, reject) => { // 请求配置处理 const { url, method = 'GET', data = {}, params = {}, header = {}, showLoading = true } = config // 处理请求参数 let requestUrl = BASE_URL + url let queryString = '' if (Object.keys(params).length > 0) { queryString = Object.keys(params) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`) .join('&') requestUrl += (requestUrl.includes('?') ? '&' : '?') + queryString } // 合并请求头 const requestHeader = { ...commonHeaders, ...header } // 显示loading if (showLoading) { uni.showLoading() } // 发送请求 uni.request({ url: requestUrl, method: method.toUpperCase(), data: data, header: requestHeader, timeout: TIMEOUT, success: (response) => { // 处理响应 const res = response.data const statusCode = response.statusCode if (statusCode >= 200 && statusCode < 300) { resolve(res) } else { // 处理HTTP错误状态 handleError({ response, config }) reject(response) } }, fail: (error) => { console.log(error); // 处理网络错误 handleError({ error, config }) reject(error) }, complete: () => { // 隐藏loading if (showLoading) { uni.hideLoading() } } }) }) } // 错误处理函数 const handleError = (errorInfo) => { const { response, error, config } = errorInfo if (response) { const { statusCode, data } = response switch (statusCode) { case 401: // 未授权,清除token并根据当前页面跳转到相应的登录页 uni.removeStorageSync('token') uni.removeStorageSync('agentInfo') // 清除代理信息 delete commonHeaders['Authorization'] // 获取当前页面栈 const pages = getCurrentPages() const currentPage = pages[pages.length - 1] const currentRoute = currentPage ? currentPage.route : '' console.log(data); // 判断当前是否在代理相关页面 if (currentRoute && currentRoute.includes('agent')) { uni.redirectTo({ url: '/pages/agent/mylogin' }) // uToast.error('') uni.showToast({ title: '代理登录已过期,请重新登录', icon: "error" }) } else { uni.showToast({ title: data.message, icon: "error" }) // uToast.error('登录已过期,请重新登录') } break case 403: // 检查是否是用户被拉黑 if (data.code === 'USER_BLACKLISTED') { // 清除token并跳转到登录页 uni.removeStorageSync('token') delete commonHeaders['Authorization'] uni.redirectTo({ url: '/pages/user/mylogin' }) // uToast.error(data.message || '账户已被拉黑,请联系管理员') uni.showToast({ title: data.message || '账户已被拉黑,请联系管理员', icon: "error" }) } else if (data.code === 'PAYMENT_REQUIRED') { // 需要支付,跳转到支付页面 // 获取当前页面避免重复跳转 const currentPages = getCurrentPages() const currentPage = currentPages[currentPages.length - 1] if (!currentPage || currentPage.route !== 'pages/payment/index') { uni.redirectTo({ url: '/pages/payment/index' }) uni.showToast({ title: data.message || '您的账户尚未激活,请完成支付后再使用', icon: "error" }) // uToast.warning(data.message || '您的账户尚未激活,请完成支付后再使用') } } else { // uToast.error(data.message || '权限不足') uni.showToast({ title: data.message || '权限不足', icon: "error" }) } break case 404: // uToast.error(data.message || '请求的资源不存在') uni.showToast({ title: data.message || '请求的资源不存在', icon: "error" }) break case 422: // uToast.error(data.message || '请求参数错误') uni.showToast({ title: data.message || '请求参数错误', icon: "error" }) break case 429: // uToast.error('请求过于频繁,请稍后再试') uni.showToast({ title: '请求过于频繁,请稍后再试', icon: "error" }) break case 500: // uToast.error('服务器内部错误') uni.showToast({ title: '服务器内部错误', icon: "error" }) break // case 400: // 处理业务逻辑错误(如坏账等) // uToast.error(data.error?.message || data.message || '请求失败') // uni.showToast({ // title: data.error?.message || data.message || '请求失败', // icon: "error" // }) // break default: // uToast.error(data.error?.message || data.message || '请求失败') uni.showToast({ title: data.error?.message || data.message || '请求失败', icon: "error" }) } } else if (error) { // 网络错误 // uToast.error('网络连接失败,请检查网络设置') uni.showToast({ title: '网络连接失败,请检查网络设置', icon: "error" }) } else { // 其他错误 // uToast.error('请求配置错误') uni.showToast({ title: '请求配置错误', icon: "error" }) } } // 封装常用的请求方法 export const http = { get: (url, params = {}, config = {}) => request({ url, params, method: 'GET', ...config }), post: (url, data = {}, config = {}) => request({ url, data, method: 'POST', ...config }), put: (url, data = {}, config = {}) => request({ url, data, method: 'PUT', ...config }), delete: (url, config = {}) => request({ url, method: 'DELETE', ...config }), patch: (url, data = {}, config = {}) => request({ url, data, method: 'PATCH', ...config }) } // 设置token export const setToken = (newToken) => { if (newToken) { commonHeaders['Authorization'] = `Bearer ${newToken}` uni.setStorageSync('token', newToken) } else { delete commonHeaders['Authorization'] uni.removeStorageSync('token') } } // 文件上传API export const uploadAPI = { // 上传图片 uploadImage: (filePath, formData = {}) => { return new Promise((resolve, reject) => { uni.uploadFile({ url: BASE_URL + '/upload/image', filePath: filePath, name: 'image', formData: formData, header: { 'Authorization': commonHeaders['Authorization'] }, success: (uploadFileRes) => { const data = JSON.parse(uploadFileRes.data) resolve(data) }, fail: (error) => { reject(error) } }) }) }, // 上传文件 uploadFile: (filePath, formData = {}) => { return new Promise((resolve, reject) => { uni.uploadFile({ url: BASE_URL + '/upload/file', filePath: filePath, name: 'file', formData: formData, header: { 'Authorization': commonHeaders['Authorization'] }, success: (uploadFileRes) => { const data = JSON.parse(uploadFileRes.data) resolve(data) }, fail: (error) => { reject(error) } }) }) } } export const distributionAPI = { getLowerUsers: (params) => http.get('/agents/distribution', { params }), } export default { http, setToken, uploadAPI, distributionAPI }