NocoBase Workflow Building
You are guiding the user to create automated workflows in NocoBase.
Key Concepts
Trigger Types
| Type | Description | Mode |
|---|
| INLINECODE0 | Data change trigger | 1=create, 2=update, 3=create+update, 4=delete |
| INLINECODE1 |
Time-based trigger | 0=cron, 1=date field |
|
action | Manual button trigger | — |
Node Types
| Type | Description |
|---|
| INLINECODE3 | If/else branch (basic engine or math.js) |
| INLINECODE4 |
Update existing records |
|
create | Create new records |
|
query | Query records for use in downstream nodes |
|
sql | Execute raw SQL |
|
request | HTTP request (webhooks, external APIs) |
|
loop | Iterate over array data |
|
end | Terminate workflow (1=success, 0=failure) |
Node Linking Model
- - Nodes form a linked list:
upstreamId → INLINECODE12 - Branch nodes (condition, loop) use
branchIndex:
-
1 = true branch (condition) or loop body (loop)
-
0 = false branch (condition)
-
null = main line continuation
Variable System
| Variable | Description |
|---|
| INLINECODE17 | Field from the trigger record |
| INLINECODE18 |
ID of the trigger record |
|
{{$jobsMapByNodeKey.<key>.field}} | Result from a previous node |
|
{{$scopes.<key>.item}} | Current item in a loop |
Workflow Patterns
Pattern 1: Auto-numbering (on create)
Generate sequential IDs like PR-2026-001:
CODEBLOCK0
Pattern 2: Status Sync (on create)
Set default status when a record is created:
CODEBLOCK1
Pattern 3: Conditional Branch (on create)
Different actions based on field value:
CODEBLOCK2
Pattern 4: Field Change Trigger (on update)
React when specific fields change:
CODEBLOCK3
Pattern 5: Date-based Schedule
Trigger N days before a date field:
CODEBLOCK4
Pattern 6: Cron Schedule
CODEBLOCK5
Pattern 7: Multi-node Chain
Chain multiple nodes on the main line:
CODEBLOCK6
Workflow
Phase 1: Plan
Before creating workflows, identify:
- 1. Trigger: What event starts the workflow? (record created/updated/deleted, schedule, manual)
- Collection: Which table triggers it?
- Logic: What conditions and actions are needed?
- Target: What data gets modified?
Phase 2: Create
- 1. Create workflow with trigger config
- Add nodes in order (first node auto-links, subsequent need
upstream_id) - For branches: add condition node, then true/false branch nodes with INLINECODE23
Phase 3: Enable & Verify
- 1. Enable the workflow
- List workflows to confirm: INLINECODE24
- Inspect with: INLINECODE25
Best Practices
- 1. Title convention: Use prefixes for grouping, e.g. "AM-WF01 Auto Number"
- One workflow per concern: Don't combine unrelated logic
- Idempotent SQL: Write SQL that's safe to run multiple times
- Test before enable: Create all nodes first, then enable
- Batch cleanup: Use
nb_delete_workflows_by_prefix("AM-") to clean up - Duplicate prevention: Check
nb_list_workflows() before creating — duplicate titles cause confusion - Variable references: Always use double braces
{{$context.data.field}} — single braces won't work
NocoBase 工作流构建
您正在指导用户在 NocoBase 中创建自动化工作流。
核心概念
触发器类型
| 类型 | 描述 | 模式 |
|---|
| collection | 数据变更触发器 | 1=创建, 2=更新, 3=创建+更新, 4=删除 |
| schedule |
基于时间的触发器 | 0=cron, 1=日期字段 |
| action | 手动按钮触发器 | — |
节点类型
| 类型 | 描述 |
|---|
| condition | 条件分支(基础引擎或 math.js) |
| update |
更新现有记录 |
| create | 创建新记录 |
| query | 查询记录供下游节点使用 |
| sql | 执行原生 SQL |
| request | HTTP 请求(Webhook、外部 API) |
| loop | 遍历数组数据 |
| end | 终止工作流(1=成功, 0=失败) |
节点链接模型
- - 节点形成链表:upstreamId → downstreamId
- 分支节点(条件、循环)使用 branchIndex:
- 1 = 真分支(条件)或循环体(循环)
- 0 = 假分支(条件)
- null = 主线延续
变量系统
| 变量 | 描述 |
|---|
| {{$context.data.field}} | 触发器记录的字段 |
| {{$context.data.id}} |
触发器记录的 ID |
| {{$jobsMapByNodeKey.
.field}} | 前一个节点的结果 |
| {{$scopes..item}} | 循环中的当前项 |
工作流模式
模式 1:自动编号(创建时)
生成类似 PR-2026-001 的序列号:
步骤 1:创建工作流
nbcreateworkflow(自动采购编号, collection,
{mode: 1, collection: purchase_requests, appends: [], condition: {$and: []}})
步骤 2:添加 SQL 节点
nbaddnode(wf_id, sql, 生成编号,
{dataSource: main, sql: UPDATE purchaserequests SET requestno = \PR-\ || TOCHAR(NOW(), \YYYY\) || \-\ || LPAD((SELECT COALESCE(MAX(CAST(SUBSTRING(requestno FROM \[0-9]+$\) AS INT)),0)+1 FROM purchaserequests WHERE requestno LIKE \PR-\ || TO_CHAR(NOW(), \YYYY\) || \-%\)::TEXT, 3, \0\) WHERE id = {{$context.data.id}}})
步骤 3:启用
nbenableworkflow(wf_id)
模式 2:状态同步(创建时)
创建记录时设置默认状态:
nbcreateworkflow(默认状态, collection,
{mode: 1, collection: orders, appends: [], condition: {$and: []}})
nbaddnode(wf_id, update, 设置草稿状态,
{collection: orders, params: {filter: {id: {{$context.data.id}}}, values: {status: draft}}})
nbenableworkflow(wf_id)
模式 3:条件分支(创建时)
根据字段值执行不同操作:
nbcreateworkflow(调拨类型处理, collection,
{mode: 1, collection: transfers, appends: [], condition: {$and: []}})
条件节点
cond = nbaddnode(wf_id, condition, 是否为调拨?,
{rejectOnFalse: false, engine: basic, calculation: {group: {type: and, calculations: [{calculator: equal, operands: [{{$context.data.type}}, transfer]}]}}})
真分支:更新状态为已调拨
nbaddnode(wf_id, update, 标记为已调拨,
{collection: assets, params: {filter: {id: {{$context.data.asset_id}}}, values: {status: transferred}}},
upstreamid=condid, branch_index=1)
假分支:更新状态为已借用
nbaddnode(wf_id, update, 标记为已借用,
{collection: assets, params: {filter: {id: {{$context.data.asset_id}}}, values: {status: borrowed}}},
upstreamid=condid, branch_index=0)
nbenableworkflow(wf_id)
模式 4:字段变更触发器(更新时)
当特定字段变更时触发:
nbcreateworkflow(处置完成, collection,
{mode: 2, collection: disposals, changed: [status], condition: {status: {$eq: disposed}}, appends: []})
nbaddnode(wf_id, update, 更新资产状态,
{collection: assets, params: {filter: {id: {{$context.data.asset_id}}}, values: {status: disposed}}})
nbenableworkflow(wf_id)
模式 5:基于日期的定时任务
在日期字段前 N 天触发:
保险到期前 30 天触发
nbcreateworkflow(保险到期提醒, schedule,
{mode: 1, collection: insurance, startsOn: {field: end_date, offset: -30, unit: 86400000}, repeat: null, appends: []})
nbaddnode(wf_id, sql, 标记即将到期,
{dataSource: main, sql: UPDATE insurance SET remark = \即将到期\ WHERE id = {{$context.data.id}}})
nbenableworkflow(wf_id)
模式 6:Cron 定时任务
每个工作日早上 9 点运行
nbcreateworkflow(每日报表, schedule,
{mode: 0, startsOn: 2026-01-01T00:00:00.000Z, repeat: 0 9 1-5})
模式 7:多节点链
在主线上链式连接多个节点:
nbcreateworkflow(复杂流程, collection,
{mode: 1, collection: orders, appends: [], condition: {$and: []}})
节点 1(第一个节点,无需 upstream_id)
n1 = nbaddnode(wf_id, query, 获取客户,
{collection: customers, multiple: false, params: {filter: {id: {{$context.data.customer_id}}}}})
节点 2(链接在节点 1 之后)
n2 = nbaddnode(wf_id, update, 更新订单,
{collection: orders, params: {filter: {id: {{$context.data.id}}}, values: {customername: {{$jobsMapByNodeKey.NODEKEY.name}}}}},
upstreamid=n1id)
nbenableworkflow(wf_id)
工作流程
阶段 1:规划
创建工作流之前,确定:
- 1. 触发器:什么事件启动工作流?(记录创建/更新/删除、定时任务、手动)
- 集合:哪个表触发它?
- 逻辑:需要什么条件和操作?
- 目标:哪些数据会被修改?
阶段 2:创建
- 1. 使用触发器配置创建工作流
- 按顺序添加节点(第一个节点自动链接,后续节点需要 upstreamid)
- 对于分支:先添加条件节点,然后使用 branchindex 添加真/假分支节点
阶段 3:启用与验证
- 1. 启用工作流
- 列出工作流确认:nblistworkflows()
- 检查:nbgetworkflow(wf_id)
最佳实践
- 1. 标题规范:使用前缀分组,例如 AM-WF01 自动编号
- 一个工作流一个关注点:不要合并不相关的逻辑
- 幂等 SQL:编写可安全多次运行的 SQL
- 启用前测试:先创建所有节点,再启用
- 批量清理:使用 nbdeleteworkflowsbyprefix(AM-) 清理