// 外置配置管理 // 用于管理需要外置的配置项,如语言包、主题配置等 // 语言包配置 export const langConfig = { // 语言列表 — 与后端 Lang.php::overrides() 白名单对齐 // 增删需要后端同步改 LangOverrideModel::normalizeAppType 旁的 $allow_lang langList: ['zh-cn', 'en-us'], // 默认语言 defaultLang: 'zh-cn', // 语言包加载方式:'lazy'(按需加载)或 'preload'(预加载) loadMode: 'lazy', // 数据源开关 // 数据源开关 // local : 纯本地包,忽略 remote // remote : 本地兜底 + 后端 KV 覆写(首屏强依赖,见 bootTimeout) // hybrid : 同 remote,后端不可用时用本地 // remote-only : 完全依赖后端 /api/lang/bundle,本地 lang/ 目录可删除 source: 'remote-only', // 远端覆写相关 remote: { overridesUrl: '/api/lang/overrides', // bundle 接口(remote-only 模式下使用) bundleUrl: '/api/lang/bundle', // diff 接口(预留) diffUrl: '/api/lang/diff', // 首屏强依赖远端翻译(多租户文案强隔离),阻塞启动 // 但必须有上限避免白屏 bootTimeout: 2000, // 单次请求超时(ms) requestTimeout: 4000, // 缓存有效期(秒),与后端 Cache::set 600s 对齐;过期后后台刷新 cacheTtl: 600, // 本地缓存 key 前缀: __ // 三维隔离,与 lang.js::getOverrideStorageKey / getOverrideMemKey 保持一致 storagePrefix: 'LANG_OVR_', // 切租户/uniacid 时强制重拉 refreshOnUniacidChange: true, // 签名校验密钥,留空不校验(需与后端 LANG_SIGN_SECRET 一致) signSecret: '', } }; // 主题配置 export const themeConfig = { // 主题列表 — 与 style_color.js 顶层的 preset 名一致 themeList: ['default', 'red', 'green', 'blue', 'pink', 'gold', 'purple', 'yellow', 'black'], // 默认主题 defaultTheme: 'default', // 远端 token 覆写相关(与 langConfig 同构) // source : 'local' | 'remote' | 'hybrid' // remote.* : 首屏拉取 + 缓存 + 三态机 + 多租户多端隔离 overrideRemote: { overridesUrl: '/api/theme/overrides', bootTimeout: 2000, requestTimeout: 4000, storagePrefix: 'THEME_OVR_', refreshOnUniacidChange: true, source: 'remote', } }; // API配置 export const apiConfig = { // API请求超时时间 timeout: 30000, // 是否开启重试 retry: true, // 重试次数 retryCount: 3, // 重试间隔时间(毫秒) retryDelay: 1000 }; // 配置外置管理类 class ConfigExternal { constructor() { this.loadedConfigs = {}; this.loadPromises = {}; } /** * 加载语言包 * @param {string} lang - 语言类型 * @returns {Promise} - 加载结果 */ async loadLang(lang = langConfig.defaultLang) { if (this.loadedConfigs[`lang_${lang}`]) { return this.loadedConfigs[`lang_${lang}`]; } if (this.loadPromises[`lang_${lang}`]) { return this.loadPromises[`lang_${lang}`]; } this.loadPromises[`lang_${lang}`] = new Promise((resolve, reject) => { try { // 动态加载语言包 const langData = require(`@/lang/${lang}/common.js`).lang; this.loadedConfigs[`lang_${lang}`] = langData; resolve(langData); } catch (error) { // console.error(`加载语言包 ${lang} 失败:`, error); reject(error); } }); return this.loadPromises[`lang_${lang}`]; } /** * 加载页面语言包 * @param {string} lang - 语言类型 * @param {string} pagePath - 页面路径 * @returns {Promise} - 加载结果 */ async loadPageLang(lang = langConfig.defaultLang, pagePath) { const key = `page_${lang}_${pagePath}`; if (this.loadedConfigs[key]) { return this.loadedConfigs[key]; } if (this.loadPromises[key]) { return this.loadPromises[key]; } this.loadPromises[key] = new Promise((resolve, reject) => { try { // 动态加载页面语言包 const pageLangData = require(`@/lang/${lang}/${pagePath}.js`).lang; this.loadedConfigs[key] = pageLangData; resolve(pageLangData); } catch (error) { console.error(`加载页面语言包 ${lang}/${pagePath} 失败:`, error); resolve({}); } }); return this.loadPromises[key]; } /** * 加载主题配置(异步方式) * @param {string} theme - 主题名称 * @returns {Promise} - 加载结果 */ async loadTheme(theme = themeConfig.defaultTheme) { if (this.loadedConfigs[`theme_${theme}`]) { return this.loadedConfigs[`theme_${theme}`]; } if (this.loadPromises[`theme_${theme}`]) { return this.loadPromises[`theme_${theme}`]; } this.loadPromises[`theme_${theme}`] = new Promise((resolve, reject) => { try { // 动态加载主题配置 const themeData = require(`@/common/js/style_color.js`)['default'][theme]; // console.log('async themeData => ', themeData); this.loadedConfigs[`theme_${theme}`] = themeData; resolve(themeData); } catch (error) { console.error(`加载主题 ${theme} 失败:`, error); reject(error); } }); return this.loadPromises[`theme_${theme}`]; } } export default new ConfigExternal();