diff --git a/src/views/flow/admin/def-editor/convert.ts b/src/views/flow/admin/def-editor/convert.ts index 5e64864..59d1b72 100644 --- a/src/views/flow/admin/def-editor/convert.ts +++ b/src/views/flow/admin/def-editor/convert.ts @@ -73,7 +73,18 @@ export function toContentJson(model: EditorModel): DefJson { if (item.deadlineHours) node.deadlineHours = item.deadlineHours; nodes.push(node); linkTo(id); - cursor = id; + if (item.outlets && item.outlets.length >= 2 && item.branches) { + // 多出口(2026-10-03 P2):APPROVAL 的多条命名出边即按钮选路, + // 分支尾隐式汇合到后继(与条件分支容器完全同构) + const tails: string[] = []; + item.branches.forEach((branch, bi) => { + tails.push(...walk(branch, id, item.outlets![bi])); + }); + cursor = null; + pending = tails; + } else { + cursor = id; + } return; } if (item.kind === "notify") { @@ -323,11 +334,39 @@ export function fromContentJson(def: any): ParsedDef { if (!n) throw new Error(`引用了不存在的节点:${cur}`); if (n.type === "APPROVAL") { - if ((out[cur] || []).length !== 1) { - throw new Error(`审批节点「${n.name || cur}」的出边必须恰好 1 条`); + const heads = out[cur] || []; + if (heads.length === 1) { + list.push(toApprovalNode(n)); + cur = heads[0]; + } else if (heads.length >= 2) { + // 多出口审批:出口名=出边 name(按钮文案),复用 CONDITION 的汇合点算法 + const mergeId = findMerge(cur); + const branches = heads.map((head) => { + const r = walkList(head, mergeId); + if (r.endedAt !== mergeId) { + throw new Error("多出口审批未汇聚到同一个节点,无法还原为卡片视图"); + } + return r.list; + }); + const outlets = heads.map((head) => { + const e = edges.find((x) => x.from === cur && x.to === head); + return e && e.name ? String(e.name) : ""; + }); + if (outlets.some((o) => !o || !o.trim())) { + throw new Error(`多出口审批「${n.name || cur}」的每个出口必须命名(按钮文案)`); + } + const dup = outlets.find((o, i) => outlets.indexOf(o) !== i); + if (dup) { + throw new Error(`多出口审批出口名重复:「${dup}」(按钮文案必须唯一)`); + } + const node = toApprovalNode(n); + node.outlets = outlets; + node.branches = branches.map((b) => (b.length ? b : [createApproval()])); + list.push(node); + cur = mergeId; + } else { + throw new Error(`审批节点「${n.name || cur}」出边数非法`); } - list.push(toApprovalNode(n)); - cur = out[cur][0]; } else if (n.type === "NOTIFY") { if ((out[cur] || []).length !== 1) { throw new Error(`抄送节点「${n.name || cur}」的出边必须恰好 1 条`);