/**
|
* 载入 Document Server 的 api.js。
|
*
|
* 这个脚本挂的是全局 `window.DocsAPI`,同一页面只能载入一次,所以用单例 Promise 收口——
|
* 多个编辑器实例(或反复开关弹窗)并发调用时共用同一次加载。
|
*
|
* 地址走 `import.meta.env.VITE_GLOB_ONLYOFFICE_URL`,刻意不进 `useGlobSetting()`:
|
* 那条链路是白名单式解构(packages/types/global.d.ts → use-app-config.ts → hooks/setting),
|
* 加一个字段要改三个跨层共享包。Vite 对 VITE_ 前缀变量本就会静态替换,直接读即可。
|
*/
|
const API_PATH = '/web-apps/apps/api/documents/api.js';
|
|
let loadingPromise: null | Promise<void> = null;
|
|
export function getDocumentServerUrl(): string {
|
const url = import.meta.env.VITE_GLOB_ONLYOFFICE_URL || '';
|
return url.endsWith('/') ? url.slice(0, -1) : url;
|
}
|
|
export function loadDocsApi(): Promise<void> {
|
if ((window as any).DocsAPI?.DocEditor) return Promise.resolve();
|
if (loadingPromise) return loadingPromise;
|
|
const baseUrl = getDocumentServerUrl();
|
if (!baseUrl) {
|
return Promise.reject(new Error('未配置 VITE_GLOB_ONLYOFFICE_URL,无法加载 OnlyOffice 编辑器'));
|
}
|
|
loadingPromise = new Promise<void>((resolve, reject) => {
|
const script = document.createElement('script');
|
script.src = `${baseUrl}${API_PATH}`;
|
script.async = true;
|
script.addEventListener('load', () => resolve());
|
script.addEventListener('error', () => {
|
// 置空以允许重试:网络抖动或 DS 尚未起来时,下次打开还能再试一次
|
loadingPromise = null;
|
script.remove();
|
reject(new Error(`加载 ${baseUrl}${API_PATH} 失败,确认 Document Server 可达`));
|
});
|
document.head.append(script);
|
});
|
|
return loadingPromise;
|
}
|
|
/** 仅供测试重置单例用 */
|
export function resetDocsApiLoaderForTest() {
|
loadingPromise = null;
|
}
|