/** * @description 应用运行时配置 * * 配置加载策略: * 1. 开发环境:使用内置开发配置 * 2. 生产环境:从 window.APP_RUNTIME_CONFIG 读取(来自 app-config.js) * 3. Docker部署:启动时替换 app-config.js 中的占位符 */ // ============================================ // 类型定义 // ============================================ export interface AppRuntimeConfig { env?: string; api: { baseUrl: string; timeout: number; }; baseUrl: string; file: { downloadUrl: string; uploadUrl: string; maxSize: { image: number; video: number; document: number; }; acceptTypes: { image: string; video: string; document: string; }; }; token: { key: string; refreshThreshold: number; }; publicImgPath: string; publicWebPath: string; sso?: { platformUrl: string; workcaseUrl: string; biddingUrl: string; }; aesSecretKey?: string; features?: { enableDebug?: boolean; enableMockData?: boolean; [key: string]: any; }; } // ============================================ // 环境检测 // ============================================ const isDev = (import.meta as any).env?.DEV ?? false; // ============================================ // 开发环境配置 // ============================================ const devConfig: AppRuntimeConfig = { env: 'development', api: { baseUrl: '/api', timeout: 30000 }, baseUrl: '/', file: { downloadUrl: '/api/urban-lifeline/file/download/', uploadUrl: '/api/urban-lifeline/file/upload', maxSize: { image: 5, video: 100, document: 10 }, acceptTypes: { image: 'image/*', video: 'video/*', document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx' } }, token: { key: 'token', refreshThreshold: 300000 }, publicImgPath: '/img', publicWebPath: '/', sso: { platformUrl: '/', workcaseUrl: '/workcase', biddingUrl: '/bidding' }, aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', features: { enableDebug: true, enableMockData: false } }; // ============================================ // 生产环境默认配置(兜底) // ============================================ const prodDefaultConfig: AppRuntimeConfig = { env: 'production', api: { baseUrl: '/api', timeout: 30000 }, baseUrl: '/', file: { downloadUrl: '/api/urban-lifeline/file/download/', uploadUrl: '/api/urban-lifeline/file/upload', maxSize: { image: 5, video: 100, document: 10 }, acceptTypes: { image: 'image/*', video: 'video/*', document: '.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx' } }, token: { key: 'token', refreshThreshold: 300000 }, publicImgPath: '/img', publicWebPath: '/', sso: { platformUrl: '/', workcaseUrl: '/workcase', biddingUrl: '/bidding' }, aesSecretKey: 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=', features: { enableDebug: false, enableMockData: false } }; // ============================================ // 配置加载 // ============================================ /** * 检查值是否为未替换的占位符 */ const isPlaceholder = (value: any): boolean => { return typeof value === 'string' && value.startsWith('__') && value.endsWith('__'); }; /** * 深度合并配置,跳过占位符值 */ const mergeConfig = (target: any, source: any): any => { const result = { ...target }; for (const key in source) { const value = source[key]; if (value && typeof value === 'object' && !Array.isArray(value)) { result[key] = mergeConfig(target[key] || {}, value); } else if (!isPlaceholder(value)) { result[key] = value; } } return result; }; /** * 获取运行时配置 */ const getRuntimeConfig = (): AppRuntimeConfig => { if (isDev) { console.log('[Config] 开发环境,使用内置配置'); return devConfig; } try { const runtimeConfig = (window as any).APP_RUNTIME_CONFIG; if (runtimeConfig && typeof runtimeConfig === 'object') { // 合并配置,未替换的占位符使用默认值 const merged = mergeConfig(prodDefaultConfig, runtimeConfig); console.log('[Config] 加载运行时配置', merged); return merged; } } catch (e) { console.warn('[Config] 无法读取外部配置', e); } console.log('[Config] 使用默认生产配置'); return prodDefaultConfig; }; // 当前配置 const config = getRuntimeConfig(); // ============================================ // 导出 // ============================================ // AES 密钥 export const AES_SECRET_KEY = config.aesSecretKey || 'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI='; // 常用配置项 export const API_BASE_URL = config.api.baseUrl; export const FILE_DOWNLOAD_URL = config.file.downloadUrl; export const FILE_UPLOAD_URL = config.file.uploadUrl; export const PUBLIC_IMG_PATH = config.publicImgPath; export const PUBLIC_WEB_PATH = config.publicWebPath; // 完整配置对象 export const APP_CONFIG = { title: '泰豪电源 AI 数智化平台', name: '泰豪电源 AI 数智化平台', version: '1.0.0', copyright: '泰豪电源', env: config.env || 'production', baseUrl: config.baseUrl, api: config.api, file: config.file, token: config.token, publicImgPath: config.publicImgPath, publicWebPath: config.publicWebPath, sso: config.sso || { platformUrl: '/', workcaseUrl: '/workcase', biddingUrl: '/bidding' }, features: config.features || {} }; export default APP_CONFIG;