Files
lucky_shop/common/js/config-external.js
ZF sun 2014d27834 chore(config): adjust boot and request timeout values
2026-07-02: 延长启动超时和请求超时时间,适配慢启动和远端冷启动场景,配合迟到数据补救机制确保获取到最终数据
2026-07-02 15:21:47 +08:00

177 lines
5.6 KiB
JavaScript

// 外置配置管理
// 用于管理需要外置的配置项,如语言包、主题配置等
// 语言包配置
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',
// 首屏强依赖远端翻译(多租户文案强隔离),阻塞启动
// 但必须有上限避免白屏
// 2026-07-02: 从 2000 改为 5000 — 慢启动场景下,给首屏渲染更多时间
bootTimeout: 5000,
// 单次请求超时(ms)
// 2026-07-02: 从 4000 改为 60000 — 远端首次冷启动可能慢(CDN 边缘冷缓存/跨网段回源/MySQL JOIN)
// 配合 loadBundleTree 的"迟到数据补救"机制,即便超时也能拿到远端最终返回的数据
requestTimeout: 60000,
// 缓存有效期(秒),与后端 Cache::set 600s 对齐;过期后后台刷新
cacheTtl: 600,
// 本地缓存 key 前缀: <prefix><uniacid>_<appType>_<lang>
// 三维隔离,与 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();