| .env.development | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/utils/healthCheck.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/utils/request.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
.env.development
@@ -12,5 +12,7 @@ # VUE_APP_BASE_API = 'http://192.168.1.11/API/' #杜贺 # VUE_APP_BASE_API = http://localhost:8082/API/ # 内网地址测试 VUE_APP_BASE_API_INNER = http://192.168.1.11/API/ # 路由懒加载 VUE_CLI_BABEL_TRANSPILE_MODULES = true src/main.js
@@ -32,6 +32,8 @@ // 字典数据组件 import DictData from '@/components/DictData' import * as XLSX from 'xlsx'; import { findAvailableService } from './utils/healthCheck' import { setAxiosBaseUrl } from './utils/request' Vue.prototype.$XLSX = XLSX; // 将 XLSX 添加到 Vue 的原型上,使其在所有组件中可用。 // 全局方法挂载 Vue.prototype.getDicts = getDicts @@ -57,6 +59,8 @@ Vue.use(plugins) DictData.install() /** * If you don't want to use mock-server * you want to use MockJs for mock api @@ -66,18 +70,36 @@ * please remove it before going online! ! ! */ Vue.use(Element, { size: Cookies.get('size') || 'medium' // set element-ui default size }) const initAPP = async () => { console.log("开始执行服务健康检查..."); // 健康检查:获取可用的服务地址 let availableBaseUrl = await findAvailableService() // const sessionUrl = sessionStorage["cacheUrl"] // if(sessionUrl){ // availableBaseUrl = sessionUrl // }else { // sessionUrl = await findAvailableService(); // sessionStorage["cacheUrl"] = sessionUrl // } Vue.config.productionTip = false // 注入 Axios 全局 baseURL setAxiosBaseUrl(availableBaseUrl); new Vue({ el: '#app', router, store, render: h => h(App) }) Vue.use(Element, { size: Cookies.get('size') || 'medium' // set element-ui default size }) //弹窗点击空白不消失 Element.Dialog.props.closeOnClickModal.default = false Vue.config.productionTip = false new Vue({ el: '#app', router, store, render: h => h(App) }) //弹窗点击空白不消失 Element.Dialog.props.closeOnClickModal.default = false } initAPP(); src/utils/healthCheck.js
New file @@ -0,0 +1,69 @@ // 连接健康度校验文件 可从多个连接中筛选符合条件的链接并设置为全局连接 export const serviceList = [ { name: "API_INNER", baseUrl: process.env.VUE_APP_BASE_API_INNER || process.env.VUE_APP_BASE_API, // 内网地址, 没有的情况下,就使用外网地址 healthPath: "/Health", }, { name: "API_INNER", baseUrl: process.env.VUE_APP_BASE_API, // 外网地址 healthPath: "/Health", }, ]; /** * 检测单个服务健康状态 * @param {Object} service - 服务配置(baseUrl + healthPath) * @returns {Promise<String|null>} 可用的 baseUrl,失败返回 null */ export const checkServiceHealth = async (service) => { const { baseUrl, healthPath } = service; console.log(baseUrl) if (!baseUrl) return null; return new Promise(async (resolve, reject) => { try { // 健康检查请求(超时 3 秒,不携带 Token,避免未登录拦截) const response = await fetch(`${baseUrl}${healthPath}`, { method: "GET", timeout: 3000, headers: { "Content-Type": "application/json", }, }); if (response.ok) { console.log(`服务 ${service.name} 健康,地址:${baseUrl}`); resolve(baseUrl) // return baseUrl; } } catch (error) { console.error(`服务 ${service.name} 连接失败:`, error.message); resolve(null) // return null; } }) }; /** * 批量检测所有服务,返回第一个可用的 baseUrl * @returns {Promise<String>} 可用的服务基础地址(失败则抛出异常) */ export const findAvailableService = async () => { // 并行检测所有服务(提高效率) const healthCheckPromises = serviceList.map((item) => { return checkServiceHealth(item) }); console.log(healthCheckPromises) const healthResult = await Promise.race(healthCheckPromises); // 竞速模式,检测到健康的链接就立刻返回 console.log(healthResult) // 筛选可用的 baseUrl(取第一个有效地址) const availableBaseUrl = healthResult if (availableBaseUrl) { return availableBaseUrl; } else { // 所有服务均不可用,抛出异常(后续在初始化时捕获) throw new Error("所有服务健康检查失败,请检查服务状态或网络配置"); } }; src/utils/request.js
@@ -15,7 +15,7 @@ // 创建axios实例 const service = axios.create({ // axios中请求配置有baseURL选项,表示请求URL公共部分 baseURL: process.env.VUE_APP_BASE_API, baseURL: "", // baseUrl 置空,后续注入 // 超时 timeout: null }) @@ -150,4 +150,13 @@ }) } /** * 动态设置 Axios 全局 baseURL(核心:初始化后注入健康检查通过的地址) * @param {String} baseUrl - 健康检查通过的服务地址 */ export const setAxiosBaseUrl = (baseUrl) => { service.defaults.baseURL = baseUrl; console.log(`Axios 全局 baseURL 已设置:${baseUrl}`); }; export default service