import { BaseConf } from "@/types/Basics"; /** * 配置优先级(高 → 低): * ① window.__APP_CONFIG__:线上运行时配置,index.html 引导脚本在应用模块加载前同步拉取 * /<应用>/<前端目标>/api/env-config?target=xxx(projman 配置管理在线维护、双写 Nacos)写入 * ② import.meta.env.VITE_*:仅本地开发(vite dev --mode dev 读 .env.dev)——值可自由指本地 * 或线上地址,供联调切换;build(production mode)时 .env/.env.production 均不存在, * VITE_* 恒为 undefined,本层自动跳过,产物不含任何环境值 * ③ 同域推导兜底:env-config 拉取失败(线上后端/Nacos 不可用)时框架至少能渲染; * ssoHost/relayConf 为空 → 登录与跨域中转不可用——与后端不可用状态一致,可接受。 */ const env = import.meta.env; // ③ 同域推导兜底:context 段取当前路径首段(/userbase/front/ → userbase),与服务端 context-path 对齐 const ctxSeg = (window.location.pathname.split("/").filter(Boolean)[0] || "") as string; const origin = window.location.origin; let conf: BaseConf = { baseHost: origin, ssoHost: "", serviceHost: ctxSeg ? `${origin}/${ctxSeg}` : origin, relayConf: { ziyuankuHost: "", zhuanxiangHost: "", }, isMock: false, isDebug: env.DEV, }; // 逐键覆盖:只覆盖来源里实际出现且非空的键(含 relayConf 二级逐键合并),未出现的键沿用底层值 const applyConf = (target: any, source: any) => { if (!source || typeof source !== "object") return; const { relayConf, ...flat } = source; Object.keys(flat).forEach(key => { if (flat[key] !== undefined && flat[key] !== null && flat[key] !== "") { (target as any)[key] = flat[key]; } }); if (relayConf && typeof relayConf === "object") { if (!target.relayConf || typeof target.relayConf !== "object") target.relayConf = {}; Object.keys(relayConf).forEach(key => { if (relayConf[key]) target.relayConf[key] = relayConf[key]; }); } }; // ② 本地开发(.env.dev;构建产物中恒 undefined → 自动跳过) applyConf(conf, { baseHost: env.VITE_BASE_HOST, ssoHost: env.VITE_SSO_HOST, serviceHost: env.VITE_SERVICE_HOST, relayConf: { ziyuankuHost: env.VITE_ZIYUANKU_HOST, zhuanxiangHost: env.VITE_ZHUANXIANG_HOST, }, isMock: env.VITE_IS_MOCK === "true", }); // ① 线上运行时配置(最高优先,覆盖前面所有) applyConf(conf, (window as any).__APP_CONFIG__); // HTTPS 自动升级:当前页面是 https 时,将所有 http:// 配置项升级为 https:// if ("https:" === document.location.protocol) { Object.keys(conf).forEach(element => { if (typeof conf[element] === "string" && conf[element].indexOf("http://") > -1) { conf[element] = conf[element].replace("http://", "https://"); } }); // relayConf 内部也需要处理 if (conf.relayConf) { Object.keys(conf.relayConf).forEach(key => { const val = (conf.relayConf as any)[key]; if (typeof val === "string" && val.indexOf("http://") > -1) { (conf.relayConf as any)[key] = val.replace("http://", "https://"); } }); } } export default conf;