Skip to content

ast-workflow 工作流编辑

工作流结构编辑插件,以 JSON 代码形式直接编辑工作流的 Schema 定义,适合需要精确控制工作流逻辑的场景。

插件功能

  • 基于 Monaco Editor 的 JSON 编辑器,支持语法高亮、自动补全和错误提示
  • 实时同步工作流画布变更,订阅 workflowSchemaChange 事件自动更新编辑器内容
  • 保存时自动校验 JSON 格式,解析异常时阻止保存并提示错误
  • 必须包含 NodeStart 开始节点(可能导致工作流执行异常)

工作流 DSL 结构

工作流 DSL 由 节点(nodes)边(edges) 两个核心数组组成,类似于流程图中的"工位"和"传送带":

json
{
  "nodes": [],
  "edges": []
}

节点结构(WorkflowNode)

节点是工作流的基本执行单元,每个节点代表一个操作步骤:

json
{
  "id": "node-1i6g7fbo",
  "type": "NodeComponent",
  "position": { "x": 100, "y": 200 },
  "data": {
    "snippet": {
      "name": "物料事件",
      "component": "NodeComponent",
      "icon": "icon-bangding-fill",
      "schema": {
        "props": {
          "id": null,
          "component": null,
          "event": [{ "type": null }]
        }
      }
    },
    "configure": {
      "canConfig": false
    },
    "isActive": true,
    "props": {}
  }
}

节点字段说明

字段类型说明
idstring节点唯一标识,如 "node-1i6g7fbo"
typestring节点类型,对应内置节点类型名称
positionobject画布位置坐标,包含 xy
dataobject节点数据,包含 snippet、configure、props 等

data.snippet 字段

snippet 是节点的"标签牌",定义了节点的展示信息和配置模板:

字段类型说明
namestring节点显示名称,如 "开始""物料事件"
componentstring节点组件类型,与 type 字段对应
iconstring节点图标类名
schema.propsobject节点配置属性模板,null 值表示待填充

data.configure 字段

configure 控制节点的编辑行为:

字段类型说明
canConfigboolean是否允许在属性面板中配置
isShowboolean是否在节点列表中显示(如开始节点默认隐藏)

data.props 字段

props 是节点的运行时配置值,结构与 snippet.schema.props 对应。例如 NodeComponent 的 props:

json
{
  "id": "section_header",
  "component": "View",
  "event": [
    { "type": "click" }
  ]
}

边结构(WorkflowEdge)

边定义了节点之间的连接关系和数据流向:

json
{
  "id": "edge-abc123",
  "source": "node-start",
  "target": "node-component",
  "sourceHandle": "output",
  "targetHandle": "input"
}
字段类型说明
idstring边唯一标识
sourcestring源节点 ID(数据发送方)
targetstring目标节点 ID(数据接收方)
sourceHandlestring源端口标识,如 "output""event-{branchId}"
targetHandlestring目标端口标识,通常为 "input"
dataobject可选,边的附加数据

端口类型(Ports)

端口是节点上的连接点,决定了节点可以如何被连接:

端口类型handle 方向说明
inputtarget输入端口,接收上游数据
outputsource输出端口,向下游传递数据
errorsource错误端口,节点执行异常时触发
elsesource否定端口,条件不满足时触发
if-{branchId}source条件分支端口,条件满足时触发(动态端口)
event-{branchId}source事件分支端口,特定事件触发时执行(动态端口)

动态端口if-{branchId}event-{branchId} 中的 {branchId} 会被替换为实际的分支标识,一个节点可以有多个动态端口。

节点与页面事件联动

工作流与页面 DSL 通过 NodeComponent 节点实现联动。页面组件的 events 字段中 handler 指向工作流节点 ID,而工作流中的 NodeComponent 节点则定义了对应的组件和事件信息:

页面 DSL 侧

json
{
  "id": "section_header",
  "component": "View",
  "events": [
    {
      "id": "evt_click_001",
      "name": "onClick",
      "handler": {
        "type": "JSExpression",
        "value": "this.__workflow__.execute('node-1i6g7fbo', { eventType: 'click', eventData: event })"
      }
    }
  ]
}

工作流 DSL 侧

json
{
  "id": "node-1i6g7fbo",
  "type": "NodeComponent",
  "data": {
    "snippet": {
      "name": "物料事件",
      "component": "NodeComponent",
      "schema": {
        "props": {
          "id": "section_header",
          "component": "View",
          "event": [{ "type": "click" }]
        }
      }
    }
  }
}

两者通过节点 ID node-1i6g7fbo 关联:页面事件触发时调用 this.__workflow__.execute('node-1i6g7fbo', ...),工作流引擎找到对应节点并执行后续流程。

完整示例

以下是一个包含开始节点、物料事件节点和设置状态节点的完整工作流 DSL:

json
{
  "nodes": [
    {
      "id": "node-start",
      "type": "NodeStart",
      "position": { "x": 100, "y": 100 },
      "data": {
        "snippet": {
          "name": "开始",
          "component": "NodeStart",
          "icon": "icon-yunhang",
          "schema": { "props": {} }
        },
        "configure": { "canConfig": false, "isShow": false },
        "isActive": true,
        "props": {}
      }
    },
    {
      "id": "node-1i6g7fbo",
      "type": "NodeComponent",
      "position": { "x": 350, "y": 100 },
      "data": {
        "snippet": {
          "name": "物料事件",
          "component": "NodeComponent",
          "icon": "icon-bangding-fill",
          "schema": {
            "props": {
              "id": "section_header",
              "component": "View",
              "event": [{ "type": "click" }]
            }
          }
        },
        "configure": { "canConfig": false },
        "isActive": true,
        "props": {
          "id": "section_header",
          "component": "View",
          "event": [{ "type": "click" }]
        }
      }
    },
    {
      "id": "node-set-state",
      "type": "NodeSetState",
      "position": { "x": 600, "y": 100 },
      "data": {
        "snippet": {
          "name": "设置状态",
          "component": "NodeSetState",
          "icon": "icon-zhuangtai",
          "schema": {
            "props": {
              "stateKey": "count",
              "stateValue": ""
            }
          }
        },
        "configure": { "canConfig": true },
        "isActive": true,
        "props": {
          "stateKey": "count",
          "stateValue": "this.state.count + 1"
        }
      }
    }
  ],
  "edges": [
    {
      "id": "edge-1",
      "source": "node-start",
      "target": "node-1i6g7fbo",
      "sourceHandle": "output",
      "targetHandle": "input"
    },
    {
      "id": "edge-2",
      "source": "node-1i6g7fbo",
      "target": "node-set-state",
      "sourceHandle": "event-0",
      "targetHandle": "input"
    }
  ]
}

执行流程:工作流启动 → 开始节点 → 物料事件节点(等待 section_header 组件的 click 事件)→ 事件触发后 → 设置状态节点(将 count 加 1)。

执行类型(ExecutionType)

每个节点执行器定义了其启动方式:

类型说明
AUTO"auto"自动执行,工作流启动时自动运行
TRIGGER"trigger"触发执行,需要外部事件触发(如组件点击)
DEPENDENCY"dependency"依赖执行,等待上游节点执行完成后自动触发