NocoBase 界面搭建:将操作按钮绑定工作流,实现数据操作自动化
【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase
本文介绍 NocoBase 界面搭建中「操作按钮绑定工作流」的完整机制:哪些操作按钮可以绑定、支持哪几类工作流触发事件、同时绑定多个工作流时的执行顺序规则,并结合plugin-workflow-action-trigger与plugin-workflow-custom-action-trigger两个插件的源码,剖析「触发参数如何传递、同步/异步工作流如何分组执行、请求如何被拦截」的底层实现。读完本文,你既能按官方文档正确配置按钮级工作流绑定,也能从源码层面理解触发链路与排障要点。
什么是“绑定工作流”
在 NocoBase 的界面搭建中,部分操作按钮(表单的“提交”、“保存”按钮,数据行中的“更新数据”、“删除”按钮,以及独立的“触发工作流”按钮)可以在操作设置中配置绑定工作流,将该提交操作与工作流关联起来,实现数据的自动化处理(参见 绑定工作流 原始文档)。
典型应用场景:订单表单点击“提交”后自动触发审批流程;表格行点击“删除”前先经过一道预校验;或者通过一个自定义“触发工作流”按钮,对当前选中记录发起一条完全自定义的自动化流程。
从源码结构看,界面按钮与后端触发器之间有明确的分工:
plugin-workflow-action-trigger负责常规的“操作触发”(action 类型),在 Plugin.ts 中通过workflowPlugin.triggers.register('action', new ActionTrigger(workflowPlugin))向工作流引擎注册action触发器;plugin-workflow-custom-action-trigger负责“触发工作流”按钮使用的“自定义操作事件”,其 CustomActionTrigger.ts 在触发器配置 Schema 中额外要求声明上下文类型(单条记录 / 多条记录 / 全局),这对应文档中“触发工作流”按钮一行的独立能力。
前端侧,按钮上的工作流绑定配置由客户端组件完成,例如 ActionTriggerConfig.tsx 与 TriggerWorkflowActionModels.tsx。
支持的操作按钮和工作流类型
这是该功能的核心约束矩阵,配置前务必确认组合是否受支持(完整表格继承自官方文档):
| 操作按钮 \ 工作流类型 | 操作前事件 | 操作后事件 | 审批事件 | 自定义操作事件 |
|---|---|---|---|---|
| 表单的“提交”、“保存”按钮 | ✅ | ✅ | ✅ | ❌ |
| 数据行(表格、列表等)中的“更新数据”按钮 | ✅ | ✅ | ✅ | ❌ |
| 数据行(表格、列表等)中的“删除”按钮 | ✅ | ❌ | ❌ | ❌ |
| “触发工作流”按钮 | ❌ | ❌ | ❌ | ✅ |
四类触发事件各有对应插件与文档,官方文档中“更多”章节指向的链接在仓库中实际对应以下路径:
- 操作后事件:数据操作成功之后触发,常用于联动通知、写日志、发起下游流程;
- 操作前事件:数据操作执行之前拦截,可用于校验、阻断本次操作;这也是“删除”按钮唯一支持的绑定类型——删除不可回滚,只能做前置校验,不能做事后处理;
- 审批事件:提交后进入审批流程,由工作流中的节点(如人工节点)决定放行与否;
- 自定义操作事件:由“触发工作流”按钮显式发起,支持单条记录、多条记录或全局三种上下文。
值得注意的是,“触发工作流”按钮只能绑定自定义操作事件,且服务端会显式校验:CustomActionTrigger的 recordTriggerAction 逻辑 中,若请求未携带triggerWorkflows参数,直接抛出 400 错误(parameter "triggerWorkflows" is required),说明该按钮的触发完全由前端按钮配置驱动,而非挂靠在数据动作上。
触发原理:从按钮点击到工作流执行
以最常见的“提交/更新后触发操作后事件”为例,核心实现在 ActionTrigger.ts。
挂载点:数据动作中间件
ActionTrigger的构造函数中向数据源管理器注册了一个中间件(ActionTrigger.ts#L63-L73):
workflow.app.dataSourceManager.use(async function triggerWorkflowActionMiddleware(context, next) { await next(); const { actionName } = context.action; if (!['create', 'update'].includes(actionName)) { return; } return self.collectionTriggerAction(context); });要点:
await next()表明该中间件先放行动作本身执行(数据已经落库),再检查是否为create/update动作——这正是“操作后事件”的语义;- 只有 create/update 会进入工作流匹配逻辑,查询、删除等动作直接跳过;
- 触发器配置中的
collection字段必须指向一个真实存在的集合,配置保存时会通过validateCollectionField校验(ActionTrigger.ts#L46-L56)。
触发参数:triggerWorkflows 的格式
按钮与工作流的关联通过请求参数triggerWorkflows传递。从源码解析逻辑看,其格式为逗号分隔的工作流key,每个 key 后可选带!数据路径后缀,即形如key1!fields.a, key2(ActionTrigger.ts#L126:triggerWorkflows.split(',').map((trigger) => trigger.split('!')))。
!后的数据路径用于从响应数据中定位子记录:如果表单包含子表(嵌套关联),可以指定工作流监听的是主记录还是某个子集合中的记录;匹配时会沿着路径逐级取关联(必要时通过关联 accessor 加载,见 ActionTrigger.ts#L170-L204)。
此外,触发时还会把脱敏后的当前用户(desensitize()处理)与角色名一并注入事件上下文,工作流下游节点可以引用“操作人”信息。若工作流配置了appends(需要额外关联数据),会按主键重新findOne并加载关联,再触发。
执行分组:同步先、异步后
一个动作命中多个工作流时,代码会先按workflow.sync字段把事件分成syncGroup与asyncGroup(ActionTrigger.ts#L155-L160),这正对应官方文档中的执行顺序规则:
- 同一触发类型的工作流中同步的工作流先执行,异步的工作流后执行;
- 同一触发类型的工作流按配置顺序执行——源码中同步组按
syncGroup.entries()的顺序逐个await this.workflow.trigger(...)串行触发; - 不同触发类型之间:操作前事件一定先于操作后和审批事件执行;操作后与审批事件没有特定顺序,业务不应该依赖于配置顺序。
同步工作流可以“拦截”请求
这是源码层面最值得注意的行为。同步工作流执行后,代码根据执行状态分三种处理(ActionTrigger.ts#L253-L297):
- 执行成功(RESOLVED):正常放行,继续后续工作流;
- 被拦截(状态低于 STARTED):如果最后执行节点是
end节点,说明工作流主动要拦截本次请求——此时抛出RequestOnActionTriggerError(400),把context.state.messages作为错误信息返回给前端,数据操作在界面上会提示失败;非 end 节点导致的失败则抛出 500; - 执行完成但仍 pending:说明同步工作流卡住(例如内部存在异步等待节点),抛出 500 提示工作流挂起。
该 400 错误由插件注册的错误处理器统一转换成{ errors: [...] }响应体(ActionTrigger.ts#L75-L83),保证前端能拿到结构化错误提示。
异步工作流的延迟触发
异步工作流不会阻塞请求:scheduleAsyncWorkflowTriggers会监听响应res的finish事件,响应真正写回客户端后再统一setTimeout触发,延迟常量ASYNC_WORKFLOW_TRIGGER_DELAY_MS = 200毫秒(ActionTrigger.ts#L32、L300-L330)。单个异步工作流触发失败只记录错误日志、不影响其他工作流,也不会影响已经返回给用户的响应。
这一设计与文档中“操作后和审批事件没有特定顺序”的提示互为印证:异步事件彼此之间以及与操作完成之间都存在时序解耦,业务上不应依赖它们与主请求的先后关系。
多工作流绑定的配置实践
结合上述规则,给出配置建议:
- 能用异步就不用同步:只有需要“根据结果放行或拦截本次操作”的场景(前置校验、审批阻断)才应使用同步/操作前/审批类型;通知、日志类联动建议异步,避免拖慢用户操作响应;
- 同步工作流内部不要再放人工节点:同步工作流在请求线程内执行,包含等待人工处理等会挂起的节点会导致“同步工作流 still pending”的 500 错误;
- 删除按钮只挂操作前事件:这是文档矩阵中唯一允许的删除场景绑定,用于删除前校验;
- 表单含子表时:通过
!数据路径明确工作流监听的数据层级,避免误触发; - 操作后与审批不要混用于有顺序依赖的流程:两者顺序未定义,确有依赖时应合并到同一个工作流内部编排。
相关文档与源码索引
- 原始功能文档:绑定工作流
- 触发器文档:操作前事件、操作后事件、审批事件、自定义操作事件
- 核心源码:ActionTrigger.ts(action 触发器)、CustomActionTrigger.ts(自定义操作触发器)、Plugin.ts(触发器注册入口)
- 测试参考:trigger.test.ts 覆盖了 action 触发器的触发行为;configuration1.test.ts 等端到端用例覆盖了按钮配置流程
适用前提:以上行为以当前仓库中的插件实现为准;action触发器中间件目前仅拦截create/update动作,工作流需在界面上先启用(源码按enabledCache匹配启用的工作流)才能被按钮命中。
【免费下载链接】nocobaseNocoBase is an open-source AI + no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考