- 与 notice 同形态:hash 路由 + TablePageAlovaNew 分页 + alova 信封分支 - API 层手写(文档端点仅容器网内可达,api:gen 无通路),键名对齐后端 operationId - 审计修复:outDir 回 dist 根(CI zip 根须含 html)、main.ts 显式引入 @/api 挂载全局 Apis、 保存失败重拉回滚、路由页补只读 timeout/bodyLimit 列、详情弹窗 backendCode 恒空说明
82 lines
3.3 KiB
TypeScript
82 lines
3.3 KiB
TypeScript
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;
|