chenhaozhe
2 天以前 d26feea860e146978fbf29f3607e030c1205dc53
新增 健康接口检测 初始化时选取健康接口 并使用该接口作为全局访问接口
1个文件已添加
3个文件已修改
128 ■■■■ 已修改文件
.env.development 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/healthCheck.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.js 11 ●●●●● 补丁 | 查看 | 原始文档 | 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