/** * Material Design风格的网络请求工具 * 封装uni.request,提供统一的错误处理和加载状态 */ const BASE_URL = 'https://www.wanandroid.com' // 请求配置 const defaultConfig = { baseURL: BASE_URL, timeout: 10000, header: { 'Content-Type': 'application/json', 'Accept': 'application/json' } } // 错误码映射 const errorMessages = { 0: '请求成功', '-1': '请求失败', '-1001': '登录失效,请重新登录', 400: '请求参数错误', 401: '未授权', 403: '禁止访问', 404: '资源不存在', 500: '服务器错误', 502: '网关错误', 503: '服务不可用', 504: '网关超时' } class Request { constructor(config = {}) { this.config = { ...defaultConfig, ...config } this.interceptors = { request: [], response: [] } } // 添加请求拦截器 useRequestInterceptor(interceptor) { this.interceptors.request.push(interceptor) } // 添加响应拦截器 useResponseInterceptor(interceptor) { this.interceptors.response.push(interceptor) } // 执行请求拦截器 async runRequestInterceptors(config) { let result = config for (const interceptor of this.interceptors.request) { result = await interceptor(result) } return result } // 执行响应拦截器 async runResponseInterceptors(response) { let result = response for (const interceptor of this.interceptors.response) { result = await interceptor(result) } return result } // 统一请求方法 async request(method, url, data = {}, config = {}) { // 合并配置 const requestConfig = { ...this.config, ...config, method: method.toUpperCase(), url: url.startsWith('http') ? url : `${this.config.baseURL}${url}`, data } try { // 执行请求拦截器 const finalConfig = await this.runRequestInterceptors(requestConfig) // 显示加载状态 if (finalConfig.showLoading !== false) { uni.showLoading({ title: '加载中...', mask: true }) } // 发送请求 const [error, res] = await uni.request(finalConfig) // 隐藏加载状态 if (finalConfig.showLoading !== false) { uni.hideLoading() } if (error) { throw this.handleRequestError(error) } // 执行响应拦截器 const finalResponse = await this.runResponseInterceptors(res) // 处理业务错误 return this.handleBusinessError(finalResponse) } catch (error) { // 隐藏加载状态 uni.hideLoading() throw error } } // 处理网络错误 handleRequestError(error) { console.error('网络请求错误:', error) let message = '网络请求失败' if (error.errMsg) { if (error.errMsg.includes('timeout')) { message = '请求超时,请检查网络' } else if (error.errMsg.includes('fail')) { message = '网络连接失败' } } // 显示错误提示 uni.showToast({ title: message, icon: 'none', duration: 3000 }) return new Error(message) } // 处理业务错误 handleBusinessError(response) { const { statusCode, data } = response if (statusCode !== 200) { const message = errorMessages[statusCode] || `请求失败,状态码: ${statusCode}` uni.showToast({ title: message, icon: 'none', duration: 3000 }) throw new Error(message) } if (data && data.errorCode !== undefined) { if (data.errorCode !== 0) { const message = data.errorMsg || errorMessages[data.errorCode] || '请求失败' // 特殊处理登录失效 if (data.errorCode === -1001) { uni.showModal({ title: '提示', content: '登录已失效,是否重新登录?', success: (res) => { if (res.confirm) { // 跳转到登录页面 uni.navigateTo({ url: '/pages/login/login' }) } } }) } else { uni.showToast({ title: message, icon: 'none', duration: 3000 }) } throw new Error(message) } } return data } // GET请求 get(url, params = {}, config = {}) { return this.request('GET', url, params, config) } // POST请求 post(url, data = {}, config = {}) { return this.request('POST', url, data, config) } // PUT请求 put(url, data = {}, config = {}) { return this.request('PUT', url, data, config) } // DELETE请求 delete(url, data = {}, config = {}) { return this.request('DELETE', url, data, config) } } // 创建默认实例 const request = new Request() // 添加请求拦截器 - 添加Token request.useRequestInterceptor(async (config) => { // 从存储中获取Token const token = uni.getStorageSync('token') if (token) { config.header = { ...config.header, 'Authorization': `Bearer ${token}` } } return config }) // 添加响应拦截器 - 处理通用逻辑 request.useResponseInterceptor(async (response) => { // 可以在这里添加通用处理逻辑 return response }) // API接口定义 const api = { // 首页相关 getBanners: () => request.get('/banner/json'), getHotWords: () => request.get('/hotkey/json'), getTopArticles: () => request.get('/article/top/json'), getArticles: (page = 0, pageSize = 20) => request.get(`/article/list/${page}/json`, { page_size: pageSize }), // 搜索相关 searchArticles: (keyword, page = 0) => request.post(`/article/query/${page}/json`, { k: keyword }), // 体系相关 getTreeData: () => request.get('/tree/json'), getTreeArticles: (cid, page = 0) => request.get(`/article/list/${page}/json`, { cid }), // 项目相关 getProjectTree: () => request.get('/project/tree/json'), getProjectList: (cid, page = 1) => request.get(`/project/list/${page}/json`, { cid }), // 公众号相关 getWxChapters: () => request.get('/wxarticle/chapters/json'), getWxArticles: (id, page = 1) => request.get(`/wxarticle/list/${id}/${page}/json`), // 登录相关 login: (username, password) => request.post('/user/login', { username, password }), register: (username, password, repassword) => request.post('/user/register', { username, password, repassword }) } // 导出 export default request export { api }