1. 软件包开发
  2. 触发器

触发器是一种特殊的微代码,主要用于校验和处理数据。

  • 触发器在执行时需要考虑数据库事务。
  • 触发器由软件包服务加载,在软件包安装和更新时,统一提交给元数据服务集中存储。
  • 触发器在记录服务中统一执行。
  • 触发器中不得引用第三方包。

触发器定义

触发器文件名称以.trigger.js结尾,格式如下:

module.exports = {
    listenTo: '对象API名称',
    beforeInsert: [async] Function,
    beforeUpdate: [async] Function,
    beforeDelete: [async] Function,
    beforeFind: [async] Function,
    afterInsert: [async] Function,
    afterUpdate: [async] Function,
    afterDelete: [async] Function,
}

listenTo

对象名称,选填。如果没有定义此属性,则取文件名中第一个 . 之前的文字作为listenTo的值,支持通过通配符指向多个对象。

事件前触发

事件前触发的触发器,可以用于校验用户录入的数据是否正确,如果有问题,可以抛错,错误信息会反馈到前端操作页面;还可以结合权限控制当前操作等。

事件前触发的触发器函数都是以before前缀命名。

事件后触发

事件后触发的触发器,可以用于执行关联的事件,比如任务创建完成后发送通知给指定人员。

事件前触发的触发器函数都是以after前缀命名。

触发器函数

以下是相关触发器函数的详细规范,包括函数参数及返回值规则。

beforeInsert

▸ beforeInsert(event: BeforeTriggerEvent<A>, context: Context, logger: Logger) : void | boolean

数据新增前执行, 选填。

参数列表:

名称类型
eventBeforeTriggerEvent<A>
contextContext
loggerLogger

返回值:void | boolean

如果返回的是false,则中断操作,不执行数据插入。

beforeUpdate

▸ beforeUpdate(event: BeforeTriggerEvent<A>, context: Context, logger: Logger) : void | boolean

数据修改前执行, 选填。

参数列表:

名称类型
eventBeforeTriggerEvent<A>
contextContext
loggerLogger

返回值:void | boolean

如果返回的是false,则中断操作,不执行数据更新。

beforeDelete

▸ beforeDelete(event: BeforeTriggerEvent<A>, context: Context, logger: Logger) : void | boolean

数据删除前执行, 选填。

参数列表:

名称类型
eventBeforeTriggerEvent<A>
contextContext
loggerLogger

返回值:void | boolean

如果返回的是false,则中断操作,不执行数据删除。

beforeFind

▸ beforeFind(event: QueryTriggerEvent<A>, context: Context, logger: Logger) : void | boolean

查询数据之前执行, 选填。

参数列表:

名称类型
eventQueryTriggerEvent<A>
contextContext
loggerLogger

返回值:void | boolean

如果返回的是false,则中断操作,不执行数据查询。

afterInsert

▸ afterInsert(event: AfterTriggerEvent<A>, context: Context, logger: Logger) : void | boolean

数据新增后执行, 选填。

参数列表:

名称类型
eventAfterTriggerEvent<A>
contextContext
loggerLogger

返回值:void

afterUpdate

▸ afterUpdate(event: AfterTriggerEvent<A>, context: Context, logger: Logger) : void | boolean

数据修改后执行, 选填。

参数列表:

名称类型
eventAfterTriggerEvent<A>
contextContext
loggerLogger

返回值:void

afterDelete

▸ afterDelete(event: AfterTriggerEvent<A>, context: Context, logger: Logger) : void | boolean

数据删除后执行, 选填。

参数列表:

名称类型
eventAfterTriggerEvent<A>
contextContext
loggerLogger

返回值:void

参数类型

以下是微函数中传入的各种参数类型规范。

TriggerEvent

触发器函数被触发时的相关事件数据,有以下属性规范。

下面并没有列出当前用户所属公司 id 和当前用户 id 属性,因为它们在另一个参数 Context 中。

id: string

触发触发器事件的对象记录的唯一标识。

object_name: string

触发触发器事件的对象Api名称。

datasource_name: string

触发触发器事件的对象所属数据源Api名称。

BeforeTriggerEvent

事件前触发器函数被触发时的相关事件数据,在 TriggerEvent 的基础上扩展了以下属性规范。

doc: object

需要新增或修改的记录内容,仅beforeInsert, beforeUpdate触发器中存在此属性。

在 before 前缀的事件前触发器函数中可以变更 doc 参数值,变更后的值最终会保存到数据库中并传入到 after后缀的事件后触发器函数中。

AfterTriggerEvent

事件后触发器函数被触发时的相关事件数据,在 TriggerEvent 的基础上扩展了以下属性规范。

doc: object

需要新增或修改的记录内容,仅afterInsert, afterUpdate触发器中存在此属性。

在after后缀的事件后触发器函数中变更 doc 参数值后并不会再回写到数据库中。

previousDoc: object

修改或删除前的记录内容,仅afterUpdate, afterDelete触发器中存在此属性。

通常在after后缀的事件后触发器函数中通过 event.previousDocevent.doc 值进行比较来判断哪些字段值发生了变化。

QueryTriggerEvent

查询触发器函数被触发时的相关事件数据,在 TriggerEvent 的基础上扩展了以下属性规范。

query: QueryOptions

触发器中查询数据相关参数。

  • fields: string[] 字段名数组,选填。 例如:[‘字段名1’, ‘字段名2’]
  • filters: QueryFilters 查询条件数组, 选填。
  • sort: string 排序规则, 格式为:字段名 desc/asc,选填。例如: “name desc” 表示按名称字段倒序排序。
  • top: number 返回记录数, 选填。
  • skip: number 跳过记录数,通常用于分页显示, 选填。

以上 event.query 中的所有查询参数都可以在触发器中被改写,比如可以修改 fields 属性以放开或收缩字段查询权限,修改 filters 属性变更查询过滤条件。

Context

表示触发器函数在执行环境中的上下文参数,与微函数中的 Context 参数规范一致。

其中 context.org.idcontext.org.user.id 分别标识了触发器执行时当前用户所属公司 id 和当前用户 id。

要在触发器中进行数据交互,可以调用参数 context.org.dataApi 中的相关函数,其规范见 DataApi

另外还可以通过参数 context.org.broker 来调用微服务 Actions

Logger

输出不同级别的日志消息功能,与微函数中的 Logger 参数规范一致。

示例

beforeInsert: async function () {
    var doc = this.doc
    if (doc.code) {
        let count = await this.getObject('picklists').count({ filters: [['space', '=', doc.space], ['code', '=', doc.code]] })
        if (count > 0) {
            throw new Error("唯一编码不能重复");
        }
    }
},