import { isDev, ignoreTokens, config } from "@/config"; import { locale, t } from "../locale"; import { isNull, isObject, parse, storage } from "../utils"; import { useStore } from "../store"; import { useUi } from "@/uni_modules/cool-ui"; // 请求参数类型定义 export type RequestOptions = { url: string; // 请求地址 method?: RequestMethod; // 请求方法 data?: any; // 请求体数据 params?: any; // URL参数 header?: any; // 请求头 timeout?: number; // 超时时间 withCredentials?: boolean; // 是否携带凭证 firstIpv4?: boolean; // 是否优先使用IPv4 enableChunked?: boolean; // 是否启用分块传输 }; // 响应数据类型定义 export type Response = { code?: number; message?: string; data?: any; }; const ui = useUi(); // 请求队列(用于等待token刷新后继续请求) let requests: ((token: string) => void)[] = []; // 标记token是否正在刷新 let isRefreshing = false; // 判断当前url是否忽略token校验 const isIgnoreToken = (url: string) => { return ignoreTokens.some((e) => { const pattern = e.replace(/\*/g, ".*"); return new RegExp(pattern).test(url); }); }; /** * 通用请求方法 * @param options 请求参数 * @returns Promise */ export function request(options: RequestOptions): Promise { let { url, method = "GET", data = {}, header = {}, timeout = 60000 } = options; const { user } = useStore(); // 拼接基础url if (!url.startsWith("http")) { url = config.baseUrl + url; } // 开发环境下打印请求信息 if (isDev) { console.log(`[${method}] ${url}`); } // 获取当前token let Authorization: string | null = user.token; // 如果是忽略token的接口,则不携带token if (isIgnoreToken(url)) { Authorization = null; } return new Promise((resolve, reject) => { // 发起请求的实际函数 const next = () => { uni.request({ url, method, data, header: { Authorization, language: locale.value, ...(header as UTSJSONObject) }, timeout, success(res) { // 401 无权限 if (res.statusCode == 401) { user.logout(); ui.showToast({ message: "无权限", type: "warn", }) reject({ message: t("无权限") } as Response); } // 502 服务异常 else if (res.statusCode == 502) { ui.showToast({ message: "服务异常", type: "warn", }) reject({ message: t("服务异常") } as Response); } // 404 未找到 else if (res.statusCode == 404) { ui.showToast({ message: `[404] ${url}`, type: "warn", }) return reject({ message: `[404] ${url}` } as Response); } // 200 正常响应 else if (res.statusCode == 200) { if (res.data == null) { resolve(null); } else if (!isObject(res.data as any)) { resolve(res.data); } else { // 解析响应数据 const { code, message, data } = parse( res.data ?? { code: 0 } )!; if (code == 200 || code == 0) { resolve(data); } else { ui.showToast({ message: message ?? t("服务异常"), type: "warn", }) reject({ message: message } as Response); } } } else { ui.showToast({ message: t("服务异常"), type: "warn", }) reject({ message: t("服务异常") } as Response); } }, // 网络请求失败 fail(err) { reject({ message: err.errMsg } as Response); } }); }; next(); }); } export function useGet(url: string, data?: any, config?: RequestOptions): Promise { const options: RequestOptions = { url, data, method: 'GET', ...config, } return request(options) } export function usePost(url: string, data?: any, config?: RequestOptions): Promise { const options: RequestOptions = { url, data, method: 'POST', ...config, } return request(options) } export function usePut(url: string, data?: any, config?: RequestOptions): Promise { const options: RequestOptions = { url, data, method: 'PUT', ...config, } return request(options) } export function useDelete(url: string, data?: any, config?: RequestOptions): Promise { const options: RequestOptions = { url, data, method: 'DELETE', ...config, } return request(options) }