axios 封装权限判断、支持上传下载进度提示

复制代码
// utils/request.ts
import axios, {
  AxiosRequestConfig,
  AxiosResponse,
  
} from 'axios';
import config from '@/config/index';
import { setToken, setUserData } from '@/store/modules/getDataConfig';
import { storeData } from '@/store/index.ts';
import { message } from 'antd';


// 自定义统一响应结构
export interface ApiResponse<T = any> {
  code: number | string;
  msg: string;
  data: T;
}

const instance = axios.create({
  baseURL: `${config.url}/mer/`,
  timeout: 60000,
});

// 默认配置项(如是否需要登录)
const defaultOpt = {
  login: true,
};

function baseRequest<T = any>(
  options: AxiosRequestConfig
): Promise<ApiResponse<T>> {
  
  const getDataConfig = storeData.getState().getDataConfig;
  
  const token = getDataConfig.token;
  const headers = options.headers || {};

  if (token) {
    headers['token'] = token;
    options.headers = headers;
  }

  return new Promise((resolve, reject) => {
    instance(options)
      .then((res: AxiosResponse<ApiResponse<T>>) => {
        const data = res.data;

        if (res.status !== 200) {
          return reject({ message: '请求失败', res, data });
        }

        // 登录过期
        if (data.code === -1) {
          // message.error('登录过期,请重新登录');
          storeData.dispatch(setToken(''));
          storeData.dispatch(setUserData({}));
          window.location.href = '/login';
          return;
        }

        if (data.code === 200 || data.code === '0000') {
          resolve(data);
        } else {
          
          // message.error(data.msg || '请求错误');
          if(data.code==403){
             reject({ message: data.msg, });
              message.error("权限不足");
          }else{
            reject({ message: data.msg, res, data });
          }
         
        }
      })
      .catch(err => {
        // message.error(err?.message || '网络异常');
       
        reject({ message: err?.message || '网络异常' });
      });
  });
}

// 请求方法类型定义
type RequestMethod = <T = any>(
  url: string,
  dataOrParams?: any,
  options?: AxiosRequestConfig
) => Promise<ApiResponse<T>>;

// 构建请求对象
interface RequestInstance {
  get: RequestMethod;
  head: RequestMethod;
  post: RequestMethod;
  put: RequestMethod;
  patch: RequestMethod;
  delete: RequestMethod;
}

const request = {} as RequestInstance;

// GET/HEAD 方法(使用 params)
(['get', 'head'] as const).forEach(method => {
  request[method] = <T = any>(
    url: string,
    params: any = {},
    options: AxiosRequestConfig = {}
  ) => {
    
    return baseRequest<T>({
      url,
      method,
      params,
      ...defaultOpt,
      ...options,
    });
  };
});

// POST/PUT 等方法(使用 data)
(['post', 'put', 'patch', 'delete'] as const).forEach(method => {
  request[method] = <T = any>(
    url: string,
    data: any = {},
    options: AxiosRequestConfig = {}
  ) => {
    return baseRequest<T>({
      url,
      method,
      data,
      ...defaultOpt,
      ...options,
    });
  };
});

export default request;  

使用

复制代码
/**如果是上传文件     {headers: {'Content-Type': 'multipart/form-data'}, onUploadProgress: onProgress}, 按正常POst上传数据即可  */
   uploadFile:(data:{excel_file:File,type?:number,category_id?:number|string,file_type:number},onProgress?: (progressEvent: AxiosProgressEvent) => void)=>{
            return axios.post(
                'upload',
                data,
                {headers: {'Content-Type': 'multipart/form-data'}, onUploadProgress: onProgress},  // 监听上传进度
                
            )
        },
getPlatformClass(data:{cate_name?:string}){
            return axios.get('merchant/categoryLst',data)
        },