177 lines
5.6 KiB
TypeScript
177 lines
5.6 KiB
TypeScript
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<IAppOption>({
|
|
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<PageConfigData | null> {
|
|
if (this.globalData.pageConfigReady) {
|
|
return Promise.resolve(this.globalData.pageConfig || null);
|
|
}
|
|
return new Promise((resolve) => {
|
|
_configResolvers.push(resolve);
|
|
});
|
|
},
|
|
});
|