Archived
基线:鉴权会话+工作组+工作台三区修复+编排工作区+产品设计文档
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -20,23 +20,31 @@ export type InstanceMark = {
|
||||
/** 每行最多几个方框 —— 蛇形折行的行宽;取原型 business 预设的观感 */
|
||||
const ROW_WIDTH = 4;
|
||||
|
||||
export function packageToGraph(pkg: ProcessPackage, marks: readonly InstanceMark[] = []): FlowGraph {
|
||||
export function packageToGraph(
|
||||
pkg: ProcessPackage,
|
||||
marks: readonly InstanceMark[] = [],
|
||||
/** 活动范式(activityId → loop|flow):案例活动画绿 —— 范式住活动库,包里只有引用 */
|
||||
paradigms?: ReadonlyMap<string, string>,
|
||||
): FlowGraph {
|
||||
const markOf = new Map(marks.map((m) => [m.nodeId, m]));
|
||||
|
||||
/*
|
||||
* 手绘图存证优先:编辑器保存过,**手绘几何即呈现真相**。
|
||||
* 运行标注仍要每次现算(它是运行态,不入存证),合到存证节点的 note 上。
|
||||
*/
|
||||
const stored = readStoredDiagram(pkg.diagram);
|
||||
if (stored !== undefined) {
|
||||
return {
|
||||
...stored,
|
||||
nodes: stored.nodes.map((n) => {
|
||||
const state = stateOf(markOf.get(n.id));
|
||||
return state === undefined ? n : { ...n, note: state };
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
const nodes: FlowNode[] = pkg.nodes.map((n) => {
|
||||
const mark = markOf.get(n.id);
|
||||
const state =
|
||||
mark === undefined || !mark.activated
|
||||
? undefined
|
||||
: mark.terminal !== undefined
|
||||
? mark.terminal === 'released'
|
||||
? '已放行'
|
||||
: '已终止'
|
||||
: mark.running
|
||||
? '运行中'
|
||||
: mark.waiting
|
||||
? '等待中'
|
||||
: '已激活';
|
||||
const state = stateOf(markOf.get(n.id));
|
||||
|
||||
if (n.kind === 'gateway') {
|
||||
return {
|
||||
@@ -45,7 +53,8 @@ export function packageToGraph(pkg: ProcessPackage, marks: readonly InstanceMark
|
||||
label: n.label,
|
||||
// 并行网关画 +,异或网关画 ×(判断)
|
||||
mode: n.gateway === 'parallel' ? 'and' : 'x',
|
||||
...(n.mode === 'join' ? { sub: '汇合' } : { sub: '分叉' }),
|
||||
...(n.sub === undefined ? (n.mode === 'join' ? { sub: '汇合' } : { sub: '分叉' }) : { sub: n.sub }),
|
||||
...(n.basis === undefined ? {} : { basis: n.basis }),
|
||||
...(state === undefined ? {} : { note: state }),
|
||||
};
|
||||
}
|
||||
@@ -58,13 +67,20 @@ export function packageToGraph(pkg: ProcessPackage, marks: readonly InstanceMark
|
||||
kind: 'activity',
|
||||
label: n.label,
|
||||
code: n.id,
|
||||
...(n.sub === undefined ? {} : { sub: n.sub }),
|
||||
...(state === undefined ? {} : { note: state }),
|
||||
};
|
||||
if (n.kind === 'approval') {
|
||||
// approval **不是一种活动**:它挂在 kind:"activity" 下仅因共用同一套方框几何
|
||||
return { ...base, flavor: 'approval', owner: n.approver.position };
|
||||
}
|
||||
return { ...base, owner: n.owner.position };
|
||||
return {
|
||||
...base,
|
||||
owner: n.owner.position,
|
||||
...(paradigms?.get(n.activityId) === 'loop' ? { flavor: 'case' as const } : {}),
|
||||
...(n.in === undefined ? {} : { in: [...n.in] }),
|
||||
...(n.out === undefined ? {} : { out: [...n.out] }),
|
||||
};
|
||||
});
|
||||
|
||||
/** 蛇形折行:偶数行 L→R、奇数行 R→L —— 行的划分交给拓扑序 */
|
||||
@@ -76,13 +92,38 @@ export function packageToGraph(pkg: ProcessPackage, marks: readonly InstanceMark
|
||||
from: e.from,
|
||||
to: e.to,
|
||||
// 回边按声明走「回 A4 重开新实例」,视觉上标红以区分正向流转
|
||||
...(e.reopen ? { tone: 'bad' as const } : {}),
|
||||
...(e.tone !== undefined ? { tone: e.tone } : e.reopen ? { tone: 'bad' as const } : {}),
|
||||
...(e.label === undefined ? (e.condition === undefined ? {} : { label: e.condition }) : { label: e.label }),
|
||||
}));
|
||||
|
||||
return { nodes, rows, anchors: [], edges };
|
||||
}
|
||||
|
||||
/**
|
||||
* 手绘图存证的在场校验:`diagram` 由本仓 `graph-to-pkg` 序列化而来,结构即 FlowGraph;
|
||||
* 这里只验骨架在不在(nodes/edges 数组、非空),不逐字段复检 —— 写入侧是唯一生产者。
|
||||
*/
|
||||
function readStoredDiagram(d: Record<string, unknown> | undefined): FlowGraph | undefined {
|
||||
if (d === undefined) return undefined;
|
||||
const nodes = d['nodes'];
|
||||
const edges = d['edges'];
|
||||
if (!Array.isArray(nodes) || nodes.length === 0 || !Array.isArray(edges)) return undefined;
|
||||
return {
|
||||
nodes,
|
||||
edges,
|
||||
rows: Array.isArray(d['rows']) ? d['rows'] : [],
|
||||
anchors: Array.isArray(d['anchors']) ? d['anchors'] : [],
|
||||
manual: d['manual'] === true,
|
||||
} as FlowGraph;
|
||||
}
|
||||
|
||||
/** 运行标注:节点实例态 → 画布角注文字;未激活不标 */
|
||||
function stateOf(mark: InstanceMark | undefined): string | undefined {
|
||||
if (mark === undefined || !mark.activated) return undefined;
|
||||
if (mark.terminal !== undefined) return mark.terminal === 'released' ? '已放行' : '已终止';
|
||||
return mark.running ? '运行中' : mark.waiting ? '等待中' : '已激活';
|
||||
}
|
||||
|
||||
/** 拓扑序:回边不参与定序(否则成环),同层按声明顺序稳定排列 */
|
||||
function topologicalOrder(pkg: ProcessPackage): string[] {
|
||||
const ids = pkg.nodes.map((n) => n.id as string);
|
||||
|
||||
Reference in New Issue
Block a user