---
pkg: '@nocobase/plugin-workflow-request-interceptor'
title: "操作前事件"
description: "操作前事件触发器：在操作执行前触发工作流，如提交前校验、批量操作前处理，可阻断或修改操作。"
keywords: "工作流,操作前事件,Pre Action,提交前校验,请求拦截,NocoBase"
---
# 操作前事件

## 介绍

操作前事件插件提供了一种对操作的拦截机制，可在新增、更新和删除操作的请求提交后，被处理之前触发。

如果在触发后的流程中有“结束流程”节点被执行，或者其他节点执行失败（出错或其他未能执行完成的情况），则该表单操作将被拦截，否则预定操作将被正常执行。

搭配使用“响应消息”节点可以为该流程配置返回客户端的响应消息，以对客户端给出相应的提示信息。操作前事件可用于进行业务验证或逻辑检查，以通过或拦截客户端提交的创建、更新和删除等操作请求。

## 触发器配置

### 创建触发器

创建工作流时，类型选择“操作前事件”：

![创建操作前事件](https://static-docs.nocobase.com/2add03f2bdb0a836baae5fe9864fc4b6.png)

### 选择数据表

拦截工作流的触发器中首先要配置的是操作对应的数据表：

![拦截事件配置_数据表](https://static-docs.nocobase.com/8f7122caca8159d334cf776f838d53d6.png)

然后选择拦截模式，可以选择仅对绑定了该工作流的操作按钮拦截，也可以选择针对该数据表的所选操作都拦截（不区分来自哪个表单，也无需绑定对应工作流）：

### 拦截模式

![拦截事件配置_拦截模式](https://static-docs.nocobase.com/145a7f7c3ba440bb6ca93a5ee84f16e2.png)

目前支持的操作类型有“创建”、“更新”和“删除”，可以同时选择多个操作类型。

## 操作配置

如果触发器配置中选择了“绑定该工作流的表单提交时才触发拦截”的模式，还需要回到表单界面，在对应操作按钮上绑定该工作流：

![新增订单_绑定工作流](https://static-docs.nocobase.com/bae3931e60f9bcc51bbc222e40e891e5.png)

在绑定工作流的配置中选择对应的工作流，通常触发数据的上下文选择默认为“整个表单数据”即可：

![选择要绑定的工作流](https://static-docs.nocobase.com/78e2f023029bd570c91ee4cd19b7a0a7.png)

:::info{title=提示}
操作前事件要绑定的按钮目前仅支持使用新增或更新表单中的“提交”（或“保存”）、“更新数据”和“删除”按钮，不支持使用“触发工作流”按钮（该按钮仅可绑定“操作后事件”）。
:::

## 达成拦截的条件

在“操作前事件”中有两种条件会导致对应操作被拦截：

1. 流程执行到任意的“结束流程”节点，类似前面的使用说明中，当触发流程的数据不满足“条件判断”节点中预设的条件时，会进入“否”的分支并执行“结束流程”节点，此时流程会结束，并且请求的操作将被拦截。
2. 流程中的任意节点执行失败，包括节点执行出错，或其他异常情况，此时流程会以对应状态结束，并且请求的操作也将被拦截。例如流程中有通过“HTTP 请求”调用外部数据时，如果请求失败，该流程以失败的状态结束的同时，也会拦截对应的操作请求。

达成拦截条件后，对应的操作不再会被执行，例如提交订单被拦截后，不会生成对应的订单数据。

## 对应操作的相关参数

“操作前事件”类型的工作流中，针对不同的操作，触发器中有不同的数据可作为变量在流程中使用：

| 操作类型 \\ 变量   | “操作者” | “操作者角色标识” | 操作参数：“ID” | 操作参数：“提交的数据对象” |
| ------------------ | -------- | ---------------- | -------------- | -------------------------- |
| 创建一条记录       | ✓        | ✓                | -              | ✓                          |
| 更新一条记录       | ✓        | ✓                | ✓              | ✓                          |
| 删除单条或多条记录 | ✓        | ✓                | ✓              | -                          |

:::info{title=提示}
操作前事件的变量“触发器数据 / 操作参数 / 提交的数据对象”，不是数据库中的实际数据，只是操作提交的相关参数，如果需要数据库中的实际数据，需要在流程中通过“查询数据”节点查询出相关数据。

另外对于删除操作，在针对单条记录时，操作参数中的“ID”是一个简单的值，而在针对多条记录时，操作参数中的“ID”是一个数组。
:::

## 输出响应消息

配置好触发器之后，可以在工作流中自定义相关的判断逻辑，通常会使用“条件判断”节点的分支模式，根据具体业务条件判断结果，选择是否“结束流程”，并返回预设的“响应消息”：

![拦截流程配置](https://static-docs.nocobase.com/cfddda5d8012fd3d0ca09f04ea610539.png)

至此即完成了对应工作流的配置，并可以尝试提交一个不满足流程中条件判断配置的数据，触发拦截器的拦截逻辑，这时可以看到返回的响应消息：

![提示出错的响应消息](https://static-docs.nocobase.com/06bd4a6b6ec499c853f0c39987f63a6a.png)

### 响应消息的状态

如果在“结束流程”节点中配置的是以“成功”状态退出，且执行到该“结束流程”节点时，该操作的请求仍会被拦截，但返回的响应消息会以“成功”（而不是“错误”）的状态显示：

![成功状态的响应消息](https://static-docs.nocobase.com/9559bbf56067144759451294b18c790e.png)

## 示例

结合上面基本的使用说明，我们以一个“订单提交”场景为例，假设我们需要在用户提交订单时，对用户选择的所有产品库存进行校验，如果任意一个所选产品库存不足，则拦截该订单的提交，并返回相应的提示信息；循环检测每个产品直到所有产品的库存都充足，则通过，为用户生成订单数据。

其他步骤与说明中的相同，但由于一个订单要针对多个商品，除了在数据建模时增加“订单” <-- m:1 -- “订单详情” -- 1:m --> “产品” 的多对多关系外，还需要在“操作前事件”工作流中增加一个“循环”节点，用于循环检测每个产品的库存是否充足：

![示例_循环检测流程](https://static-docs.nocobase.com/8307de47d5629595ab6cf00f8aa898e3.png)

循环的对象选择为提交的订单数据中的“订单详情”数组：

![示例_循环对象配置](https://static-docs.nocobase.com/ed662b54cc1f5425e2b472053f89baba.png)

循环流程中的条件判断节点用于判断当前循环产品对象的库存是否充足：

![示例_循环中的条件判断](https://static-docs.nocobase.com/4af91112934b0a04a4ce55e657c0833b.png)

其他配置与基本使用中的配置相同，最终提交订单时，如果任意一个产品库存不足，则会拦截订单提交，并返回相应的提示信息。测试时也尝试在一个订单内提交多个产品，其中一个产品库存不足，另一个产品库存充足，可以看到返回的响应消息：

![示例_提交后的响应消息](https://static-docs.nocobase.com/dd9e81084aa237bda0241d399ac19270.png)

可以看到，响应消息中并未提示第一个产品“iPhone 15 pro”的库存不足，而只提示了第二个产品“iPhone 14 pro”的库存不足，这是因为在循环中，第一个产品库存充足，所以不会拦截，而第二个产品库存不足，所以拦截了订单提交。

## 外部调用

操作前事件本身注入在请求处理阶段，所以也支持通过 HTTP API 调用触发。

针对局部绑定在操作按钮上的工作流，可以这样调用（以 `posts` 表创建按钮举例）：

```bash
curl -X POST -H 'Authorization: Bearer <your token>' -H 'X-Role: <roleName>' -d \
  '{
    "title": "Hello, world!",
    "content": "This is a test post."
  }'
  "http://localhost:3000/api/posts:create?triggerWorkflows=workflowKey"
```

其中 URL 参数 `triggerWorkflows` 为工作流的 key，多个工作流用逗号分隔。该 key 可在工作流画布顶部工作流名称处鼠标悬浮后获得：

![工作流_key_查看方式](https://static-docs.nocobase.com/20240426135108.png)

以上调用发出后，将触发对应 `posts` 表的操作前事件。在对应的工作流同步处理完成后，正常创建数据并返回。

如果配置的工作流中进行到“结束节点”，则与界面操作的逻辑相同，请求将被拦截，不会创建数据。结束节点中状态配置为失败时，返回的响应状态码为 `400`，成功时为 `200`。

如果在结束节点前还配置“响应消息”节点，生成的消息也会在响应结果中返回，其中错误时的结构为：

```json
{
  "errors": [
    {
      "message": "message from 'Response message' node"
    }
  ]
}
```

“结束节点”配置为成功时的消息结构为：

```json
{
  "messages": [
    {
      "message": "message from 'Response message' node"
    }
  ]
}
```

:::info{title=提示}
由于“响应消息”节点可以在流程中添加多个，所以返回的消息数据结构为数组。
:::

如果操作前事件配置为全局模式，则在调用 HTTP API 时，无需使用 URL 参数 `triggerWorkflows` 指定对应工作流，直接调用对应的数据表操作即可触发。

```bash
curl -X POST -H 'Authorization: Bearer <your token>' -H 'X-Role: <roleName>' -d \
  '{
    "title": "Hello, world!",
    "content": "This is a test post."
  }'
  "http://localhost:3000/api/posts:create"
```

:::info{title="提示"}
通过 HTTP API 调用触发操作后事件时，也需要注意工作流的启用状态，以及数据表配置是否匹配，否则可能不会调用成功，或出现错误。
:::
