import { fetchPageConfig } from './services/site-api'; import { normalizePreviewImages } from './config/assets'; import { defaultPrintConfig } from './config/config'; import { getUser } from './utils/auth'; import { generateUUID, getAppUUID, setAppUUID } from './utils/uuid'; let _refreshGeneration = 0; const STORAGE_KEY_PAGE_CONFIG = 'pageConfig'; // Pending resolvers for getPageConfig() callers waiting on config let _configResolvers: Array<(config: PageConfigData | null) => void> = []; // app.ts App({ globalData: { env: 'release', uuid: '', user: null, printConfig: defaultPrintConfig, pageConfig: undefined, pageConfigReady: false, }, onLaunch() { try { wx.removeStorageSync('user_info'); wx.removeStorageSync('user_info_expire'); } catch { /* 旧云登录缓存清理失败不影响新凭证命名空间。 */ } const accountInfo = wx.getAccountInfoSync(); const env = accountInfo.miniProgram.envVersion || 'release'; this.globalData.env = env; let uuid = getAppUUID(); if (!uuid) { uuid = generateUUID(); setAppUUID(uuid); console.log('生成并存储 UUID', uuid); } this.globalData.uuid = uuid; if (env !== 'release') { const printConfig = wx.getStorageSync('printConfig') || defaultPrintConfig; this.globalData.printConfig = printConfig; } // 启动与回到前台共用登录 Promise,不阻塞公开页面渲染。 this.warmAuthentication(); void this.loadPageConfig(); }, onShow() { this.warmAuthentication(); if (this.globalData.pageConfigReady) void this.refreshPageConfig(); }, warmAuthentication() { void getUser().catch(() => { console.warn('静默登录暂未完成,公开浏览仍可使用'); }); }, onHide() {}, getPrintConfig(): PrintConfig { return this.globalData.printConfig || defaultPrintConfig; }, setPrintConfig(config: PrintConfig) { this.globalData.printConfig = config; wx.setStorageSync('printConfig', config); }, async loadPageConfig() { let config: PageConfigData | null = null; // L1: 数据预拉取 try { const res = await new Promise<{ fetchedData: string }>( (resolve, reject) => { wx.getBackgroundFetchData({ fetchType: 'pre', success: resolve as any, fail: reject, }); }, ); if (res.fetchedData) { const parsed = JSON.parse(res.fetchedData); config = parsed?.data || parsed; } } catch { // 预拉取失败,继续降级 } // L2: storage 缓存 if (!config) { try { const cached = wx.getStorageSync(STORAGE_KEY_PAGE_CONFIG); if (cached && typeof cached === 'object') { config = cached; } } catch { // storage 读取失败,继续降级 } } // L3: 新后端动态兜底;微信预拉取机制和地址保持不变。 const hadCachedConfig = !!config; if (!config) { try { config = await fetchPageConfig(); } catch { /* 新后端不可用时继续展示空状态,本地生成仍可使用。 */ } } // 三种数据入口都先转换预览图,旧缓存会随成功加载写回新地址。 config = normalizePreviewImages(config); // 写入 globalData if (config) { this.globalData.pageConfig = config; // 成功获取后写入 storage 缓存 try { wx.setStorageSync(STORAGE_KEY_PAGE_CONFIG, config); } catch { // storage 写入失败不影响主流程 } } // 标记就绪,通知等待中的页面 this.globalData.pageConfigReady = true; for (const resolve of _configResolvers) { resolve(config); } _configResolvers = []; // 预拉取/缓存先渲染,再用新后端刷新,避免旧静态配置长期覆盖管理修改。 if (hadCachedConfig) void this.refreshPageConfig(); }, async refreshPageConfig() { const generation = ++_refreshGeneration; try { const config = normalizePreviewImages(await fetchPageConfig()); if (generation !== _refreshGeneration) return; this.globalData.pageConfig = config; try { wx.setStorageSync(STORAGE_KEY_PAGE_CONFIG, config); } catch { /* 缓存失败不影响当前数据。 */ } for (const page of getCurrentPages()) { if ( page.route === 'pages/home/home' && typeof page.initData === 'function' ) void page.initData(config); } } catch { /* 保留已显示的数据,网络错误不清空预拉取首屏。 */ } }, getPageConfig(): Promise { if (this.globalData.pageConfigReady) { return Promise.resolve(this.globalData.pageConfig || null); } return new Promise((resolve) => { _configResolvers.push(resolve); }); }, });