feat(flow-editor): convert 双向支持多出口审批(命名出边⇄出口泳道)
This commit is contained in:
@@ -73,7 +73,18 @@ export function toContentJson(model: EditorModel): DefJson {
|
|||||||
if (item.deadlineHours) node.deadlineHours = item.deadlineHours;
|
if (item.deadlineHours) node.deadlineHours = item.deadlineHours;
|
||||||
nodes.push(node);
|
nodes.push(node);
|
||||||
linkTo(id);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (item.kind === "notify") {
|
if (item.kind === "notify") {
|
||||||
@@ -323,11 +334,39 @@ export function fromContentJson(def: any): ParsedDef {
|
|||||||
if (!n) throw new Error(`引用了不存在的节点:${cur}`);
|
if (!n) throw new Error(`引用了不存在的节点:${cur}`);
|
||||||
|
|
||||||
if (n.type === "APPROVAL") {
|
if (n.type === "APPROVAL") {
|
||||||
if ((out[cur] || []).length !== 1) {
|
const heads = out[cur] || [];
|
||||||
throw new Error(`审批节点「${n.name || cur}」的出边必须恰好 1 条`);
|
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") {
|
} else if (n.type === "NOTIFY") {
|
||||||
if ((out[cur] || []).length !== 1) {
|
if ((out[cur] || []).length !== 1) {
|
||||||
throw new Error(`抄送节点「${n.name || cur}」的出边必须恰好 1 条`);
|
throw new Error(`抄送节点「${n.name || cur}」的出边必须恰好 1 条`);
|
||||||
|
|||||||
Reference in New Issue
Block a user