import axios from "axios"; import { download } from "@/utils/tool"; import { get, isEmpty } from "lodash-es"; import qs from "qs"; // import { h } from 'vue'; import { getAuthorization, getMD5 } from "./crypto"; import router from "@/router"; import { initSyncTime, fetchTime } from "./syncServerTime"; import { local } from "@/utils/tool"; import { useAppStore } from "@/store"; import { message } from "@qmth/ui"; function getDeviceId() { let deviceId = local.get("deviceId"); if (deviceId) return deviceId; if (!deviceId) { deviceId = getMD5(Math.random() + "-" + Date.now()); local.set("deviceId", deviceId); return deviceId; } } function setAuth(config: any) { let userSession = sessionStorage.getItem("user"); if (userSession && !config.noAuth) { let user = JSON.parse(userSession).userInfo; if (!user) { return; } const timestamp = fetchTime(); const authorization = getAuthorization( { method: config.method, uri: config.url.split("?")[0].trim(), timestamp, sessionId: user.sessionId, token: user.accessToken, }, "token" ); config.headers["Authorization"] = authorization; config.headers["time"] = timestamp; } } function createService() { // 创建一个 axios 实例 const service = axios.create(); // HTTP request 拦截器 service.interceptors.request.use( (config: any) => { setAuth(config); const appStore = useAppStore(); if (config.loading) { appStore.setLoading(true); } if (config.download) { config.responseType ??= "blob"; } return config; }, (error) => { // 失败 return Promise.reject(error); } ); const rejectWhiteList: string[] = []; // HTTP response 拦截器 service.interceptors.response.use( (response: any) => { initSyncTime(new Date(response.headers.date).getTime()); const appStore = useAppStore(); if (response.config.loading) { appStore.setLoading(false); } // 以下代码看后端是否有统一在接口里增加外层code的规范 if (response.data?.code && response.data?.code !== 200) { message.error(response.data?.message); } if (response.config.download && response.config.responseType === "blob") { download(response); } return response.data; }, (error) => { if (error.response) { initSyncTime(new Date(error.response.headers.date).getTime()); } const appStore = useAppStore(); if (error.config?.loading) { appStore.setLoading(false); } const err = (text: string) => { !rejectWhiteList.includes(error.config?.url) && message.error( error.response && error.response.data && error.response.data.message ? error.response.data.message : text ); }; if (error.response) { switch (error.response.status) { case 404: err(`服务器资源不存在`); break; case 500: err(`服务器内部错误`); break; case 401: message.error("登录状态已过期"); router.replace({ name: "Login" }); break; case 403: err(`没有权限访问该资源`); break; default: err(JSON.stringify(error?.response || "未知错误")); } } else { err("请求超时,服务器无响应!"); } return Promise.reject( error.response && error.response.data ? error.response.data : null ); } ); return service; } /** * @description 创建请求方法 * @param {Object} service axios 实例 */ function createRequest(service: any) { return function (config: any) { const env = process.env; let headers = { platform: "WEB", deviceId: getDeviceId(), ...(config.headers || {}), "Content-Type": get( config, "headers.Content-Type", // "application/json;charset=UTF-8" "application/x-www-form-urlencoded" ), }; const configDefault = { method: "post", timeout: 120000, // baseURL: env.VITE_APP_PROXY_URL ? "" : env.VITE_APP_BASE_URL, baseURL: env.VITE_APP_PROXY_URL ? "" : local.get("baseUrl") || "/", data: {}, }; const option = Object.assign(configDefault, config, { headers: headers }); return service(option); }; } export function paramsSerializer(params: any) { return qs.stringify(params); } // 用于真实网络请求的实例和请求方法 export const service = createService(); export const request = createRequest(service);