/** * axios 实例 */ import axios from 'axios'; import type { AxiosResponse } from 'axios'; import { unref } from 'vue'; import router from '@/router'; import { Modal } from 'ant-design-vue'; import {API_BASE_URL, TOKEN_HEADER_NAME, LAYOUT_PATH, TENANT_ID} from '@/config/setting'; import { getToken, setToken } from './token-util'; import { logout } from './page-tab-util'; import type { ApiResult } from '@/api'; import { getHostname, getTenantId } from '@/utils/domain'; import { getMerchantId } from '@/utils/merchant'; // 获取API基础地址的函数 const getBaseUrl = (): string => { // 尝试从配置store获取后台配置的API地址 try { // 如果store中没有,则尝试从localStorage获取 const ApiUrl = localStorage.getItem('ApiUrl'); if (ApiUrl) { return ApiUrl; } } catch (error) { console.warn('获取后台配置API地址失败:', error); } // 如果后台没有配置API地址,则使用本地配置 console.log('使用本地配置的API地址:', API_BASE_URL); return API_BASE_URL; }; const service = axios.create({ baseURL: getBaseUrl() }); /** * 添加请求拦截器 */ service.interceptors.request.use( (config) => { const token = getToken(); // 添加 token 到 header(Axios 1.x 直接设置 headers) if (token && config.headers) { config.headers[TOKEN_HEADER_NAME] = token; } // 获取租户ID if (config.headers) { // 登录前场景(找回密码等)由调用方显式设置 X-Tenant-Skip, // 此时不做任何租户/企业/商户/域名头注入,避免串租户 if (config.headers['X-Tenant-Skip']) { return config; } // 附加企业ID const companyId = localStorage.getItem('CompanyId'); if (companyId) { config.headers['CompanyId'] = companyId; } // 附加商户ID if (getMerchantId()) { config.headers['MerchantId'] = getMerchantId(); } // 通过网站域名获取租户ID if (getHostname()) { config.headers['Domain'] = getHostname(); } // 解析二级域名获取租户ID(确保始终设置TenantId) config.headers['TenantId'] = getTenantId() || TENANT_ID; } return config; }, (error) => { return Promise.reject(error); } ); /** * 添加响应拦截器 */ service.interceptors.response.use( (res: AxiosResponse>) => { // 登录过期处理 if (res.data?.code === 401) { const currentPath = unref(router.currentRoute).path; if (currentPath == LAYOUT_PATH) { logout(true); } else { Modal.destroyAll(); Modal.info({ title: '系统提示', content: '登录状态已过期, 请退出重新登录!', okText: '重新登录', onOk: () => { logout(false, currentPath); } }); } return Promise.reject(new Error(res.data.message)); } // token 自动续期 const token = res.headers[TOKEN_HEADER_NAME.toLowerCase()]; if (token) { setToken(token); } return res; }, (error) => { return Promise.reject(error); } ); export default service;