123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /**
- * 网络请求工具类
- * 封装uni-app的request方法
- */
- import errorHandler from './errorHandler.js';
- import { apiBaseUrl } from '@/common/config.js';
- // 基础URL,可以根据环境变量等动态设置
- const BASE_URL = apiBaseUrl;
- // 请求超时时间
- const TIMEOUT = 60000;
- // 请求拦截器
- const requestInterceptor = (config) => {
- // 获取token
- const token = uni.getStorageSync('token');
-
- // 获取 CSRF token
- const csrfToken = uni.getStorageSync('csrfToken');
-
- // 设置请求头
- if (!config.header) {
- config.header = {};
- }
-
- // 添加token到请求头
- if (token) {
- config.header['Authorization'] = `Bearer ${token}`;
- }
-
- // 添加 CSRF token 到请求头
- if (csrfToken) {
- config.header['X-CSRF-Token'] = csrfToken;
- }
-
- // 添加内容类型
- if (!config.header['Content-Type']) {
- config.header['Content-Type'] = 'application/json';
- }
-
- // 添加基础URL
- if (!config.url.startsWith('http')) {
- config.url = BASE_URL + config.url;
- }
-
- // 如果是 POST 请求,也可以添加到请求体
- if (config.method === 'POST' && config.data) {
- config.data._csrf = csrfToken;
- }
-
- return config;
- };
- // 错误提示
- const showError = (message, duration = 2000) => {
- // 避免重复显示相同的错误提示
- if (showError.lastMessage === message && Date.now() - showError.lastTime < 3000) {
- return;
- }
-
- uni.showToast({
- title: message,
- icon: 'none',
- duration: duration
- });
-
- // 记录最后显示的错误信息和时间
- showError.lastMessage = message;
- showError.lastTime = Date.now();
- };
- // 初始化错误提示状态
- showError.lastMessage = '';
- showError.lastTime = 0;
- // 错误码映射表
- const ERROR_CODE_MAP = {
- 400: '请求参数错误',
- 401: '登录已过期,请重新登录',
- 403: '没有权限执行此操作',
- 404: '请求的资源不存在',
- 500: '服务器错误,请稍后重试',
- 502: '网关错误',
- 503: '服务不可用,请稍后重试',
- 504: '网关超时'
- };
- // 响应拦截器
- const responseInterceptor = (response) => {
- // 这里可以对响应数据做统一处理
- if (response.statusCode === 200) {
- // 服务器正常响应
- const { data } = response;
-
- // 检查是否有特定错误码
- if (data.status === 999 || data.code === 999) {
- // 微信 code 无效错误
- const error = new Error(data.message || '微信登录失败: code无效');
- error.status = 999;
- return Promise.reject(error);
- }
- // 处理成功响应 - 适配不同的返回格式
- if (data.status === 2000 || data.code === 0 || data.code === 2000) {
- // 如果返回的是完整数据对象,直接返回
- if (data.data) {
- return data.data;
- }
- // 如果没有data字段,但有其他用户信息字段,返回整个对象
- if (data.openid || data.userId || data.user_id) {
- return data;
- }
- // 默认返回
- return data;
- } else {
- // 业务错误
- const error = errorHandler.handleBusinessError(data);
- return Promise.reject(error);
- }
- } else {
- // HTTP错误
- const error = errorHandler.handleHttpError(response.statusCode, response);
- return Promise.reject(error);
- }
- };
- // 请求方法
- const request = (options = {}) => {
- return new Promise((resolve, reject) => {
- // 应用请求拦截器
- options = requestInterceptor(options);
-
- // 设置超时时间
- if (!options.timeout) {
- options.timeout = TIMEOUT;
- }
-
- // 发起请求
- uni.request({
- ...options,
- success: (res) => {
- try {
- // 应用响应拦截器
- const data = responseInterceptor(res);
- resolve(data);
- } catch (error) {
- errorHandler.logError(error, 'request.responseInterceptor');
- reject(error);
- }
- },
- fail: (err) => {
- const error = errorHandler.handleRequestFail(err);
- errorHandler.logError(error, 'request.fail');
- reject(error);
- }
- });
- });
- };
- // 封装常用请求方法
- const http = {
- get(url, data = {}, options = {}) {
- return request({
- url,
- data,
- method: 'GET',
- ...options
- });
- },
-
- post(url, data = {}, options = {}) {
- return request({
- url,
- data,
- method: 'POST',
- ...options
- });
- },
-
- put(url, data = {}, options = {}) {
- return request({
- url,
- data,
- method: 'PUT',
- ...options
- });
- },
-
- delete(url, data = {}, options = {}) {
- return request({
- url,
- data,
- method: 'DELETE',
- ...options
- });
- },
-
- // 上传文件
- upload(url, filePath, name = 'file', formData = {}, options = {}) {
- return new Promise((resolve, reject) => {
- // 获取token
- const token = uni.getStorageSync('token');
-
- // 设置请求头
- const header = options.header || {};
- if (token) {
- header['Authorization'] = `Bearer ${token}`;
- }
-
- // 添加基础URL
- if (!url.startsWith('http')) {
- url = BASE_URL + url;
- }
-
- uni.uploadFile({
- url,
- filePath,
- name,
- formData,
- header,
- success: (res) => {
- try {
- // 上传接口可能返回的是字符串
- if (typeof res.data === 'string') {
- res.data = JSON.parse(res.data);
- }
-
- // 应用响应拦截器
- const data = responseInterceptor({
- statusCode: res.statusCode,
- data: res.data
- });
- resolve(data);
- } catch (error) {
- reject(error);
- }
- },
- fail: (err) => {
- showError('文件上传失败');
- reject(err);
- }
- });
- });
- }
- };
- export default http;
|