4. 接一条审批流

订单不能由业务员直接改成“已通过”。先实现提交和主管决策,再把结果接入工作流。

本章目标与起点

先用业务员和主管账号完成上一章的访问检查。本章让订单按规则从草稿变为待审批,再由主管决定结果。完成后既要能看到订单状态,也要能找到对应的工作流执行记录。

订单状态与工作流执行状态

订单状态回答“这笔业务现在到哪一步”,工作流状态回答“这次后台处理有没有完成”。主管已经通过订单,但后续任务仍在执行,是两个不同的状态,界面不能把它们混成一个“成功”。

version 用来标识订单状态的变化。同一版本的审批结果重试时复用同一个事件标识;新的状态变化才产生新的版本。这也是下一章避免重复通知的基础。

先确定状态变化

当前状态谁操作操作新状态
草稿或已驳回订单本人提交审批待审批
待审批主管通过已通过
待审批主管驳回,填写意见已驳回
已通过任意用户再次审批拒绝,状态不变

每次状态变化增加 version。更新时同时匹配旧版本,避免两个审批请求都成功。本练习保留当前状态和最近一次意见;完整审批历史、加签和转交不在本例范围内。

人工等待放在哪里

当前工作流提供 Condition、Run 和 Terminate 等指令。本教程把“等待主管处理”保存在订单的 submitted 状态中;主管操作后才触发结果工作流。不要创建一个长时间运行的 Run 节点来等待人工点击,也不要假设存在内置人工审批节点。

让 AI Agent 实现审批和结果工作流

读取当前应用的 Workflow Skill、Authorization Skill 和教程订单接口。

按本章状态表增加提交、通过、驳回操作。服务端验证身份、权限、归属、当前状态与版本;驳回必须填写意见。禁止业务员直接写 status=approved。详情页只显示当前账号可执行的操作。

创建 workflows/tutorial-order-result/workflow.ts,使用已安装的 RunInstruction。输入为 orderId 和 version。先让 Run 脚本读取并核对已保存的审批结果,下一章再接通知。

审批结果先持久化,再通过 workflowServiceToken 调用 trigger('tutorial-order-result', { orderId, version }, { eventKey })。eventKey 固定为 tutorial-order:<订单ID>:decision:<版本>。明确处理 accepted、skipped 和抛错;界面区分“结果已保存”和“后续工作流是否受理”。

提供仅主管可用的“补发审批结果”操作,用于尚未受理或受理情况不明时按同一个事件键再次派发。不重复改变审批状态,不增加版本。已经确认失败的工作流不能声称用同一个事件键就能重新执行。

检查工作流定义和应用代码:

pnpm nocobase workflow check workflows/tutorial-order-result
pnpm typecheck
pnpm test

工作流检查通过只说明定义合法,还不能证明业务脚本执行成功。

启用并实际审批

管理员进入设置中的工作流页面,找到“订单审批结果”并启用当前定义。开发环境可以发现工作流源码;生产环境需要把工作流产物随应用构建部署。

业务员打开自己的草稿并点击“提交审批”。换主管登录,打开同一张订单,确认“待审批”后点击“通过”。刷新页面,状态应保持“已通过”。

主管查看待审批订单并执行通过或驳回

到工作流执行记录中核对订单 ID、版本和执行状态。accepted 是受理回执,不是执行成功;异步执行和节点错误需要继续查看。

再检查三条路径

  • 业务员直接请求审批接口,应被拒绝。
  • 主管驳回另一张订单,意见不能为空;申请人看到“已驳回”及意见,并可再次提交。
  • 连续点击两次“通过”,只能完成一次状态变化,第二次应提示状态已变化。

如果结果已经保存但工作流未启用,启用后按同一事件键补发。如果执行记录已经失败,先查节点错误和已完成的副作用,再决定补偿方式;不要随机更换事件键反复发送。

下一步:发通知。