221 lines
5.5 KiB
TypeScript
221 lines
5.5 KiB
TypeScript
/**
|
||
* @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;
|