import axios from "axios"; import { Message, Loading } from "element-ui"; import { debounce } from "lodash-es"; import store from "../store/index"; import { getToken } from "./getToken.js"; import { toLoginPage, toResetPwdPage } from "./logout"; let axiosBaseURL; let axiosTimeout; let workflowLoginURL; if (import.meta.env.PROD) { //生产环境 const ProjectConfig = window.ProjectConfig; axiosBaseURL = ProjectConfig.axiosBaseURL; axiosTimeout = ProjectConfig.axiosTimeout; workflowLoginURL = ProjectConfig.workflowLoginURL; } else { //非生产环境 axiosBaseURL = "/api"; axiosTimeout = 1000 * 30; workflowLoginURL = "http://workflow-newapi.probim.cn/api/User/Home/Login"; } export const http = axios.create({ withCredentials: false, baseURL: axiosBaseURL, timeout: axiosTimeout }); //loading对象 let loadingInstance; //当前正在请求的数量 let needLoadingRequestCount = 0; //显示loading function showLoading(target) { // 后面这个判断很重要,因为关闭时加了抖动,此时loading对象可能还存在, // 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading if (needLoadingRequestCount === 0 && !loadingInstance) { loadingInstance = Loading.service({ target: target || "body", fullscreen: false, lock: true, text: "Loading...", // spinner: "", // background: "", // customClass: "", }); } needLoadingRequestCount++; } //隐藏loading function hideLoading() { needLoadingRequestCount--; needLoadingRequestCount = Math.max(needLoadingRequestCount, 0); //做个保护 if (needLoadingRequestCount === 0) { //关闭loading toHideLoading(); } } //防抖:将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时, loading闪烁的问题。 const toHideLoading = debounce(() => { loadingInstance?.close(); loadingInstance = null; }, 300); //处理响应的结果,返回统一结构 function handleTheResponse(response) { console.log(`axios包装过的响应${response.config.url}`, response); if (response.config.showLoading === true) { hideLoading(); } // { // // `data` 由服务器提供的响应 // data: {}, // // `status` 来自服务器响应的 HTTP 状态码 // status: 200, // // `statusText` 来自服务器响应的 HTTP 状态信息 // statusText: 'OK', // // `headers` 是服务器响应头 // // 所有的 header 名称都是小写,而且可以使用方括号语法访问 // // 例如: `response.headers['content-type']` // headers: {}, // // `config` 是 `axios` 请求的配置信息 // config: {}, // // `request` 是生成此响应的请求 // // 在node.js中它是最后一个ClientRequest实例 (in redirects), // // 在浏览器中则是 XMLHttpRequest 实例 // request: {} // } let responseData = response.data; if (response.status === 200) { if (responseData?.code === 40001) { toLoginPage(); return; } if(responseData?.code === 40002) { toResetPwdPage(); return; } const targetUrl = response.config.url.toLowerCase(); if (/^\s*$/g.test("" + responseData)) { responseData = { code: 1, message: "无响应数据", data: null, }; } else if (targetUrl === "https://bnah-web-api.biaddti.com/api/video/video/getvideo") { //摄像头视频 responseData = { code: responseData?.Ret === 1 ? 0 : 1, message: responseData?.Msg ?? "服务异常", data: responseData?.Data ?? null, }; } else if (targetUrl.startsWith(workflowLoginURL.toLowerCase())) { //协同登录,响应结构不一样,需要单独处理 responseData = { code: responseData?.Ret === 1 ? 0 : 1, message: responseData?.Msg ?? "协同登录服务异常", data: responseData?.Data ?? null, }; } else if (targetUrl.startsWith("https://api.help.bj.cn/apis/weather")) { // { // "status": "0", //反馈代码 0成功 // "msg": "反馈信息", //反馈信息 // "cityen": "changchun", //城市名称英文 // "city": "长春", //城市名称 // "citycode": "101060101", //城市编码 // "temp": "10", //实时温度 // "tempf": "50", //华氏温度 // "wd": "西风", //风向 // "wden": "W", //风向英文 // "wdforce": "3级", //风力 // "wdspd": "<12km/h", //风速 // "uptime": "12:00", //更新时间 // "weather": "晴", //天气状况 // "weatheren": "Sunny", //天气状况英文 // "weatherimg": "d00", //天气状况图标 // "stp": "994", //气压 // "wisib": "35000", //能见度 // "humidity": "46%", //湿度 // "prcp": "0", //降雨 // "prcp24h": "2.2", //24小时降雨量 // "aqi": "22", //AQI // "pm25": "20", //PM2.5 // "today": "10月17日(星期一)" //今天日期 // } //网上找的天气信息接口,由服务端代理,响应结构不一样,需要单独处理 if (responseData?.status === "0") { responseData = { code: 0, message: null, data: responseData, }; } else { responseData = { code: 1, message: "天气服务异常", data: null, }; } } } else { return { code: 1, message: responseData?.message ?? "服务异常", data: responseData, }; } if (!responseData || responseData.code !== 0) { Message.error({ message: responseData?.message ?? "服务异常", duration: 1000 * 3 }); } return responseData; } //处理错误,返回统一结构 function handleTheError(error) { console.log(`axios包装过的错误${error.config.url}`, error); if (error.config?.showLoading === true) { hideLoading(); } const responseData = { code: -999, data: null }; if (error.response) { const { data, status, statusText } = error.response; if (status === 500 && /^\s*$/gi.test(data + "")) { responseData.message = "服务异常,无响应数据"; } else { responseData.data = data; responseData.message = `${statusText ?? "服务异常,请稍后再试"}`; } } else if (error.request) { responseData.message = "未收到服务端响应,请稍后再试"; } else { responseData.message = "未发送请求,请检查请求参数是否正确"; } Message.error({ message: responseData.message, duration: 1000 * 3 }); return responseData; } //添加请求拦截器 http.interceptors.request.use( (config) => { if (config.showLoading === true) { showLoading(config.loadingTarget); } if (config.withProjectId !== false) { config.headers["projectId"] = store.getters["common/currentProjectId"]; } if (config.withToken !== false) { config.headers["token"] = getToken(); } return config; }, (error) => { // console.log("request-error", error); //todo 封装成固定结构 {code,data,message} return handleTheError(error); }, ); //响应拦截器 http.interceptors.response.use( (response) => { //todo 封装成固定结构 {code,data,message} return handleTheResponse(response); }, (error) => { //todo 封装成固定结构 {code,data,message} return handleTheError(error); }, ); // 引擎接口 let modelaxiosUrl const ProjectConfig = window.ProjectConfig; modelaxiosUrl = ProjectConfig.modelUrl; export const modelhttp = axios.create({ withCredentials: false, baseURL: modelaxiosUrl, timeout: axiosTimeout }); //添加请求拦截器 modelhttp.interceptors.request.use( (config) => { if (config.showLoading === true) { showLoading(config.loadingTarget); } if (config.withProjectId !== false) { config.headers["projectId"] = store.getters["common/currentProjectId"]; } if (config.withToken !== false) { config.headers["token"] = getToken(); } return config; }, (error) => { // console.log("request-error", error); //todo 封装成固定结构 {code,data,message} return handleTheError(error); }, ); //响应拦截器 modelhttp.interceptors.response.use( (response) => { //todo 封装成固定结构 {code,data,message} return handleTheResponse(response); }, (error) => { //todo 封装成固定结构 {code,data,message} return handleTheError(error); }, );