Files
ai-agent-admin/web/apps/web-ele/src/main.ts
T

149 lines
4.4 KiB
TypeScript

import { initPreferences } from '@vben/preferences';
import { merge, unmountGlobalLoading } from '@vben/utils';
import { overridesPreferences } from './preferences';
/**
* 从 URL 路径中解析 appCode 和模式
* URL 格式:
* - /app/:appCode/... (正常模式)
*/
function getAppInfoFromUrl(): { appCode: null | string } {
const path = window.location.pathname;
const appMatch = path.match(/^\/app\/([^/]+)/);
if (appMatch?.[1]) {
return { appCode: appMatch[1] };
}
return { appCode: null };
}
/**
* 根据 appCode 获取应用详情
*/
async function getApplicationByCode(
appCode: string,
): Promise<null | { id: string }> {
try {
const apiURL = import.meta.env.VITE_GLOB_API_URL || '';
const response = await fetch(
`${apiURL}/api/core/applications/code/${appCode}`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
},
);
if (response.ok) {
const result = await response.json();
// 后端直接返回应用数据,不包装 code/data
if (result && result.id) {
return result;
}
}
} catch (error) {
console.warn('[应用加载] 获取应用详情失败', error);
}
return null;
}
/**
* 从后端加载UI配置
* 如果加载失败则返回空对象,使用前端默认配置
* @param applicationId 应用ID,不传则获取主应用配置
*/
async function loadBackendPreferences(
applicationId?: string,
): Promise<Record<string, any>> {
try {
const apiURL = import.meta.env.VITE_GLOB_API_URL || '';
const url = applicationId
? `${apiURL}/api/core/ui_config/preferences?applicationId=${applicationId}`
: `${apiURL}/api/core/ui_config/preferences`;
const response = await fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
if (response.ok) {
const result = await response.json();
// 后端直接返回配置数据,不包装 code/data
if (result && typeof result === 'object') {
console.log(
'[配置加载] 成功从后端加载UI配置',
applicationId ? `(应用: ${applicationId})` : '(主应用)',
);
return result;
}
}
} catch (error) {
console.warn('[配置加载] 后端UI配置加载失败,使用前端默认配置', error);
}
return {};
}
/**
* 应用初始化完成之后再进行页面加载渲染
*/
async function initApplication() {
// name用于指定项目唯一标识
// 用于区分不同项目的偏好设置以及存储数据的key前缀以及其他一些需要隔离的数据
const env = import.meta.env.PROD ? 'prod' : 'dev';
const appVersion = import.meta.env.VITE_APP_VERSION;
const baseNamespace = `${import.meta.env.VITE_APP_NAMESPACE}-${appVersion}-${env}`;
// 1. 检查是否为子应用模式,获取 appCode 和 applicationId
const { appCode } = getAppInfoFromUrl();
let applicationId: string | undefined;
if (appCode) {
const appInfo = await getApplicationByCode(appCode);
applicationId = appInfo?.id;
console.log('[应用初始化] 子应用模式', {
appCode,
applicationId,
});
} else {
console.log('[应用初始化] 主应用模式');
}
// 2. 根据应用模式生成不同的 namespace,确保主应用和子应用的 localStorage 隔离
// 主应用: vben-admin-1.0.0-dev
// 子应用正常模式: vben-admin-1.0.0-dev-crm
let namespace = baseNamespace;
if (appCode) {
namespace = `${baseNamespace}-${appCode}`;
}
// 3. 从后端加载UI配置(传递 applicationId 获取对应应用的配置)
const backendPreferences = await loadBackendPreferences(applicationId);
console.log('[配置加载] 后端配置:', backendPreferences);
console.log('[配置加载] 前端默认配置:', overridesPreferences);
// 4. 合并配置:后端配置优先级高于前端配置
// defu/merge 的特点是第一个参数优先,所以后端配置放前面
const finalPreferences = merge({}, backendPreferences, overridesPreferences);
console.log('[配置加载] 合并后配置:', finalPreferences);
// 5. app偏好设置初始化
await initPreferences({
namespace,
overrides: finalPreferences,
});
// 启动应用并挂载
// vue应用主要逻辑及视图
const { bootstrap } = await import('./bootstrap');
await bootstrap(namespace);
// 移除并销毁loading
unmountGlobalLoading();
}
initApplication();