参考

CEL 表达式

公式字段、验证规则、可见性、共享和流程条件背后的表达式语言 —— ObjectOS 在哪里使用它、几个示例,以及 objectstack.ai 上的完整语言规范。

完整规范:objectstack.ai 上的表达式(CEL)。本页是摘要:ObjectOS 在哪里使用它,以及几个示例。

ObjectOS 在任何需要一个小巧、安全的表达式的定义中使用 CEL(Common Expression Language):它没有 副作用,没有 I/O,并且在服务器上求值。表达式能以 record 看到被求值的记录(以 previous 看到它之前的状态),并且 —— 在有执行用户的地方 —— 以 current_user 看到该用户。

ObjectOS 在哪里使用它

位置表达式决定什么
公式字段字段的值,由记录推导而来
字段的 requiredWhen、visibleWhen、readonlyWhen该字段在这条记录上是否必填、是否显示、是否可编辑
验证规则是否拒绝一次写入(验证规则)
共享规则授予一组用户哪些记录(记录访问)
动作的 visible / disabled是否提供该按钮
流程的启动条件及其分支流程是否运行,以及走哪个分支(流程)
字段的 defaultValue新记录的初始值

示例

公式字段 —— 明细行合计:

subtotal: Field.formula({
  label: 'Subtotal',
  expression: F`record.quantity * record.unit_price`,
}),

验证 —— 关闭日期必须在将来。script 规则的 condition 描述的是无效的 记录:当它为真时,写入会被拒绝。

// One validation rule, an entry of the object's `validations`
{
  type: 'script',
  name: 'close_date_in_future',
  message: 'Close date must be in the future',
  condition: P`record.close_date <= today()`,
}

可见性 —— 只在商机赢单后才显示某个字段:

close_reason: Field.textarea({
  label: 'Close reason',
  visibleWhen: P`record.stage == 'closed_won'`,
}),

流程条件 —— 只在金额较大时启动记录变更流程:

// The `config` of a `start` node; the rest of the flow is omitted (see Flows).
config: {
  objectName: 'opportunity',
  triggerType: 'record-after-update',
  condition: P`record.amount >= 1000`,
}

权限检查

从 ObjectStack 17.5 起,current_user.can(object, verb) 用于询问执行用户是否持有 某项对象权限,依据该用户的有效权限作答:

discount: Field.percent({
  label: 'Discount',
  defaultValue: cel`current_user.can('crm_quote', 'edit') ? 10 : 0`,
}),

服务器会在选择项选项的 visibleWhen 中(用户不能选择的选项会以 invalid_option 被拒绝)、在公式字段中以及在 CEL defaultValue 中回答它。在不携带权限数据的求值 中 —— 验证规则就是一例 —— can() 会被拒绝而不是被猜测,表达式随之失败。

当表达式有错时

它不会静默失败。格式错误的表达式,或者点名了对象上不存在的字段的表达式,会让 os compile 失败,并给出位置和一个"你是不是想写"的提示。在运行时,错误的表达式 会抛出一个可归因的错误,而不是求值为 null 或 false,所以故障会出现在日志和审计 轨迹中,而不是悄悄地破坏一个公式值或一次守卫判定。

另请参阅