刘光辉
14 小时以前 0dfe84494048ce27ba8449831782128412d3eb13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import type { DocumentField, FieldApplyResult, FieldChange } from '../domain/types';
import { applyFieldsCommand, inspectFieldsCommand } from './commands';
import type { ApplyResult, AscGlobal, InspectResult } from './types';
 
interface LifecycleCallbacks { onReady: () => void; onThemeChanged: (theme: unknown) => void }
 
export interface OnlyOfficeBridge {
  applyFields(changes: FieldChange[]): Promise<FieldApplyResult[]>;
  bindLifecycle(callbacks: LifecycleCallbacks): () => void;
  getRuntimeOptions(): unknown;
  inspectFields(): Promise<DocumentField[]>;
}
 
function parseResult<T>(raw: unknown): T {
  const result: unknown = typeof raw === 'string' ? JSON.parse(raw) : raw;
  if (typeof result !== 'object' || result === null || Array.isArray(result) || !('ok' in result) || typeof result.ok !== 'boolean') {
    throw new Error('编辑器命令返回无效结果');
  }
  return result as T;
}
 
export function createOnlyOfficeBridge(asc: AscGlobal): OnlyOfficeBridge {
  function callCommand<T>(command: () => string, scopeKey: string, payload: unknown): Promise<T> {
    return new Promise((resolve, reject) => {
      asc.scope[scopeKey] = payload;
      try {
        asc.plugin.callCommand(command, false, true, (raw) => {
          try { resolve(parseResult<T>(raw)); } catch (error) { reject(error); }
          finally { delete asc.scope[scopeKey]; }
        });
      } catch (error) {
        delete asc.scope[scopeKey];
        reject(error);
      }
    });
  }
 
  async function inspectFields(): Promise<DocumentField[]> {
    const result = await callCommand<InspectResult>(inspectFieldsCommand, 'elnTemplateFillInspect', {});
    if (!result.ok) throw new Error(result.error || '读取内容控件失败');
    return result.fields;
  }
 
  async function applyFields(changes: FieldChange[]): Promise<FieldApplyResult[]> {
    const result = await callCommand<ApplyResult>(applyFieldsCommand, 'elnTemplateFillChanges', changes);
    if (!result.ok) throw new Error(result.error || '应用字段失败');
    return result.results;
  }
 
  function bindLifecycle(callbacks: LifecycleCallbacks): () => void {
    const originalInit = asc.plugin.init;
    const originalTheme = asc.plugin.onThemeChanged;
    asc.plugin.init = callbacks.onReady;
    asc.plugin.onThemeChanged = (theme) => { asc.plugin.onThemeChangedBase(theme); callbacks.onThemeChanged(theme); };
    return () => {
      if (asc.plugin.init === callbacks.onReady) asc.plugin.init = originalInit;
      asc.plugin.onThemeChanged = originalTheme;
    };
  }
 
  return { applyFields, bindLifecycle, getRuntimeOptions: () => asc.plugin.info?.options, inspectFields };
}