提交条件与权限

第 4 课 · 共 7 课 约 8 分钟

把「什么时候不能改、谁不能改」写成条件,配好失败信息;角色、提交条件与数据权限各挡什么。

本课目标

读完这一课,你将能够

  • 把「什么时候不能改、谁不能改」写成提交条件,并写好失败信息
  • 用 and、or、not 组合条件,选对运算符
  • 分清 roles、提交条件与数据权限各挡什么

提交条件是什么

上一节决定了改什么、怎么改,这一节决定什么时候不能改。提交条件把业务规则编进数据编辑权限:订单已经确认就不能再确认,审批人不能批自己起草的单。所有条件满足才执行,任何一条不满足,整个请求被拒绝。条件读到的是提交那一刻对象的当前值,所以它也能挡住基于过期画面的操作:别人刚把订单确认了,你手里那个还显示「草稿」的确认请求就会被拦下。

每条条件是一次比较:左值、运算符、右值。值可以是参数、对象参数的某个属性、当前用户(id、name、role)或写死的字面量。运算符按值的形状分两组:

SINGLE VALUE

单个值

is、isNot、matches(正则)、lt、lte、gt、gte、isNull、isNotNull。

MANY VALUES

多个值

includes、includesAny、isIncludedIn、eachIs、eachIsNot:用来判断列表,或「是否在这几个值之内」。

几条条件可以用 and、or、not 组合,也可以嵌套。每一条提交条件都有自己的 failureMessage。同一个对象类型上可以有很多 Action,各有各的提交条件,confirm-order 的条件不会影响 hold-work-order。

示例:approve-purchase-order

示例工厂的采购订单从 draft 开始,批准后变成 approved。批准要满足三件事:订单是草稿;批准人不是起草人;数量超过 5000 的单只有 developer 能批。

{
  "kind": "actionType",
  "apiName": "approve-purchase-order",
  "title": "批准采购订单",
  "schema": {
    "parameters": [
      { "name": "purchaseOrder", "type": "object", "objectType": "purchaseOrder", "title": "采购订单", "required": true }
    ],
    "rules": [
      { "type": "modifyObject", "objectType": "purchaseOrder", "object": "$purchaseOrder", "values": { "status": "approved" } }
    ],
    "roles": ["developer", "editor"],
    "submissionCriteria": [
      {
        "condition": { "type": "comparison", "left": { "param": "purchaseOrder", "property": "status" }, "operator": "is", "right": { "literal": "draft" } },
        "failureMessage": "只有草稿采购订单可以批准"
      },
      {
        "condition": { "type": "comparison", "left": { "param": "purchaseOrder", "property": "ownerId" }, "operator": "isNot", "right": { "user": "id" } },
        "failureMessage": "不能批准自己起草的采购订单,请换另一位有权限的同事批准"
      },
      {
        "condition": {
          "type": "or",
          "conditions": [
            { "type": "comparison", "left": { "param": "purchaseOrder", "property": "qty" }, "operator": "lte", "right": { "literal": 5000 } },
            { "type": "comparison", "left": { "user": "role" }, "operator": "is", "right": { "literal": "developer" } }
          ]
        },
        "failureMessage": "数量超过 5000 的采购订单只有 developer 可以批准"
      }
    ],
    "actionLog": true
  }
}

三条提交条件是「且」的关系:都满足才执行。第三条自己用了 or:数量不超过 5000,或者执行人是 developer,二者有一个成立就行,所以只需要一句失败信息。roles 在条件之前先挡一道,这里只允许 developer 和 editor。

随口一问

「校验失败」

好的交代

「不能批准自己起草的采购订单,请换另一位有权限的同事批准」

失败信息是写给执行人看的一句话,界面、命令行和智能体看到的一字不差。写清为什么被拦、下一步怎么办。

再看 report-output 的两条条件(submissionCriteria 数组)。第一条用 isIncludedIn 判断状态是否在两个值之内:

[
  {
    "condition": { "type": "comparison", "left": { "param": "workOrder", "property": "status" }, "operator": "isIncludedIn", "right": { "literal": ["released", "running"] } },
    "failureMessage": "只有已下达或生产中的工单可以报产出"
  },
  {
    "condition": { "type": "comparison", "left": { "param": "goodQty" }, "operator": "gte", "right": { "param": "workOrder", "property": "goodQty" } },
    "failureMessage": "累计合格数不能少于已经报过的数"
  }
]

第二条要小心:goodQty 是必填参数,一定有值,所以能这样比较。如果对可选的 scrapQty 写同样的条件,没传时比较的左边是空值,gte 判为不通过,会把根本没打算改报废数的调用也拦下。要写成「没传,或者不小于现在的值」,也就是 or 加 isNull。

三道关:roles、提交条件、数据权限

ROLES

roles:哪类人

roles 决定谁能执行 Action。缺省允许 developer、member、editor。只读分享的访客不能执行。Open to Internet 应用有匿名只读入口,匿名访客也不能执行 Action。

CRITERIA

提交条件:这一次

这一次能不能:看参数、看对象现在的值、看当前用户。同一个对象类型上的每个 Action 各有自己的提交条件。

DATA ACCESS

数据权限:哪些对象

数据权限检查 Object Type、行、列和 Markings。修改属性要能读到它当前的值;删除要能读到整个对象;链接两端都要可见。第 9 门课讲这些控制。

三道关各挡各的,不能互相代替。比如「只有质量经理能暂停工单」,应该写进 roles 与提交条件,而不是指望界面上不显示按钮。提交条件与「谁能编辑这个 Action 的定义」也是两回事。

写完条件,用 --validate-only 逐条验证:故意传一张已经确认的订单,看返回里是哪一条不通过、显示的是哪一句话。

另有两条通用做法里的提醒:不要对用户组、标记、组织成员身份用 not,受限令牌可能没带这个属性,条件反而通过;列表参数用在提交条件里,元素最多 1,000 个。

拦得住错误,还要留得下证据。下一节讲通知与写回这些副作用,再下一节讲日志与撤销。

要点

  • 提交条件把业务规则编进编辑权限,全部满足才执行。
  • 条件按参数、对象属性、当前用户判断,可用 and、or、not 组合。
  • 失败信息写给执行人:说清为什么被拦、下一步怎么办。
  • 可选参数没传时,比较的一边是空值;要用 or 加 isNull 兜底,别误拦。
  • roles、提交条件、数据权限各挡各的,不能互相代替。

练一练

为工单写提交条件

用示例工厂的工单练习:先想清楚业务规则,再翻译成条件。

第一条:工单现在必须是 planned。第二条:工单的 plannedQty 不能超过所选产线的 capacityPerShift(本练习假定一张工单一个班次做完)。写出 JSON,并给每条配失败信息。

小测

选一个答案,马上看解析。

Q1「审批人不能批准自己起草的采购订单」应该怎么表达?

Q2要表达「数量不超过 5000,或者执行人是 developer」,怎么组合?

Q3通过公开链接打开应用的访客点了批准,会怎样?

延伸阅读