export interface AnnotationInsertSpec {
|
alias: string;
|
placeholder: string;
|
tag: string;
|
}
|
|
export interface AnnotationInsertResult {
|
error?: string;
|
ok: boolean;
|
}
|
|
export interface FlowVersionPropertiesSpec {
|
newFlowVersionId: string;
|
revisionFlowVersionId: string;
|
}
|
|
/**
|
* This command is serialized into the ONLYOFFICE editor context. Keep it self-contained:
|
* it may access only Api and Asc.scope, not imports or closure state.
|
*/
|
export function insertAnnotationControlCommand(): string {
|
try {
|
const spec = Asc.scope.dmsQianpiyeInsert as AnnotationInsertSpec | undefined;
|
if (!spec || typeof spec.tag !== 'string' || !spec.tag || typeof spec.alias !== 'string'
|
|| typeof spec.placeholder !== 'string' || !spec.placeholder) {
|
throw new Error('签批页标注配置无效');
|
}
|
const document = Api.GetDocument();
|
if (!document || typeof document.GetAllContentControls !== 'function') {
|
throw new Error('当前编辑器不支持读取内容控件');
|
}
|
const before = document.GetAllContentControls().filter((control) => control.GetTag?.() === spec.tag);
|
if (typeof Api.CreateInlineLvlSdt !== 'function' || typeof Api.CreateRun !== 'function'
|
|| typeof Api.CreateParagraph !== 'function') {
|
throw new Error('当前编辑器不支持签批页标注控件');
|
}
|
|
const control = Api.CreateInlineLvlSdt();
|
const run = Api.CreateRun();
|
const paragraph = Api.CreateParagraph();
|
if (!control || !run || !paragraph || run.AddText?.(spec.placeholder) !== true
|
|| control.AddElement?.(run, 0) !== true || typeof paragraph.AddInlineLvlSdt !== 'function') {
|
throw new Error('创建签批页标注失败');
|
}
|
// AddInlineLvlSdt is a write-only API in ONLYOFFICE 9.4 and returns void.
|
paragraph.AddInlineLvlSdt(control);
|
if (control.SetTag?.(spec.tag) !== true || control.SetAlias?.(spec.alias) !== true
|
|| control.SetLock?.('unlocked') !== true) {
|
throw new Error('创建签批页标注失败');
|
}
|
if (typeof control.SetAppearance === 'function') {
|
control.SetAppearance('boundingBox');
|
}
|
if (typeof document.InsertContent !== 'function' || document.InsertContent([paragraph], true) !== true) {
|
throw new Error('插入签批页标注失败');
|
}
|
|
const after = document.GetAllContentControls().filter((item) => item.GetTag?.() === spec.tag);
|
if (after.length !== before.length + 1) {
|
throw new Error('签批页标注插入后校验失败');
|
}
|
return JSON.stringify({ ok: true });
|
} catch (error: unknown) {
|
return JSON.stringify({
|
ok: false,
|
error: error instanceof Error ? error.message : String(error),
|
});
|
}
|
}
|
|
/**
|
* Marks the version selection in the in-editor document. ONLYOFFICE 9.4 cannot delete custom
|
* properties, so the qianpiye save callback is responsible for the final server-side upsert.
|
*/
|
export function stageFlowVersionPropertiesCommand(): string {
|
try {
|
const spec = Asc.scope.dmsQianpiyeFlowVersionProperties as FlowVersionPropertiesSpec | undefined;
|
if (!spec || typeof spec.newFlowVersionId !== 'string' || !spec.newFlowVersionId
|
|| typeof spec.revisionFlowVersionId !== 'string' || !spec.revisionFlowVersionId) {
|
throw new Error('签批页流程版本配置无效');
|
}
|
const document = Api.GetDocument();
|
const properties = document?.GetCustomProperties?.();
|
if (!properties || typeof properties.Add !== 'function' || typeof properties.Get !== 'function') {
|
throw new Error('当前编辑器不支持保存签批页流程版本');
|
}
|
for (const [key, value] of [
|
['DMS_NEW_FLOW_VERSION_ID', spec.newFlowVersionId],
|
['DMS_EDIT_FLOW_VERSION_ID', spec.revisionFlowVersionId],
|
]) {
|
const existing = properties.Get(key);
|
if (existing === value) continue;
|
// Add can append a duplicate in ONLYOFFICE 9.4. The qianpiye save callback uses the last
|
// value as the requested selection, then writes one canonical property for each key.
|
if (properties.Add(key, value) !== true) throw new Error('保存签批页流程版本失败');
|
}
|
return JSON.stringify({ ok: true });
|
} catch (error: unknown) {
|
return JSON.stringify({
|
ok: false,
|
error: error instanceof Error ? error.message : String(error),
|
});
|
}
|
}
|
|
export function parseInsertResult(value: unknown): AnnotationInsertResult {
|
try {
|
const result: unknown = JSON.parse(String(value));
|
if (typeof result === 'object' && result !== null && !Array.isArray(result)
|
&& typeof (result as Record<string, unknown>).ok === 'boolean') {
|
const item = result as Record<string, unknown>;
|
return {
|
ok: item.ok as boolean,
|
...(typeof item.error === 'string' ? { error: item.error } : {}),
|
};
|
}
|
} catch {
|
// The command result is untrusted editor output; expose a normalized error below.
|
}
|
return { ok: false, error: '签批页标注命令返回无效' };
|
}
|