feat(flow-editor): convert 双向支持多出口审批(命名出边⇄出口泳道)

This commit is contained in:
chenxing
2026-10-03 14:05:39 +08:00
parent e057e3bd8b
commit 2dd7135753
+44 -5
View File
@@ -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 条`);