流程表达式
一句话:流程表达式是「一段可复用的取人表达式」的登记处——把「审批人是谁」写成一段表达式(求值结果是用户编号),登记在这里,之后在 BPMN 设计器的用户任务面板里挑一条挂上;派单时引擎现场求值,算出该谁审批。
与流程监听器一样:本页只有 BPMN 设计器会用
本页登记的表达式只能被 BPMN 设计器引用(用户任务属性面板里「审批人」选「流程表达式」后的挑选弹窗)。
简易设计器里也有一个同名的「流程表达式」审批人选项,但它是手写文本框,不读本页数据(源码里留着「后续要支持选择已经存好的表达式」的待办注释)。所以用简易设计器建模时,本页登记的表达式用不上,得把表达式原文抄进文本框。
功能在哪
- 菜单路径:工作流程 → 流程管理 → 流程表达式
- 地址栏路由:
/bpm/manager/process-expression - 主要权限:
bpm:process-expression:query/create/update/delete/export

界面认识
| 区域 | 作用 | 常用操作 |
|---|---|---|
| 查询区 | 名字 / 状态 / 创建时间区间 | 「搜索」「重置」 |
| 工具条 | 整页级动作 | 「新增」(后端虽有导出接口,但本页没有导出按钮) |
| 列表 | 序号 / 编号 / 名字 / 状态 / 表达式 / 创建时间 | 行内「编辑」「删除」 |
| 表达式列 | 原样显示表达式文本,过长截断、悬停看全 | 只读 |
| 状态列 | 启用 / 禁用开关 | 点开关直接改状态 |
常用操作
新增表达式
- 点「新增」;
- 填「名字」——给人看的说明(如「请假天数超 3 天转总监」这类语义名);
- 「状态」默认已选开启;
- 在「表达式」里写一段 Flowable 表达式,求值结果必须是用户编号(单个或一组);
- 点「确 定」。

结果:列表多一行。此时只是登记,还没挂到任何流程——要到 BPMN 设计器里挂上才生效。
表达式怎么写
表达式在派单那一刻由流程引擎求值,结果转成用户编号集合。常见三类写法:
| 写法 | 例子 | 含义 |
|---|---|---|
| 取流程变量 | ${managerUserId} | 变量 managerUserId 里存的用户编号 |
| 调 Spring Bean | ${deptService.getLeaderUserIds(deptId)} | 调后端 Bean 方法,返回值转用户编号 |
| 常量 | 1 | 就是「用户编号 1」这个人 |
求值结果不是用户编号,派单就会出错或派空
引擎把求值结果按用户编号(Long)转换。表达式返回字符串、对象、或一个不存在的编号时:轻则派单候选为空(走节点「审批人为空时」的兜底),重则派单直接抛异常、流程卡住。
保存本页时不校验表达式——任何文本都能存进去,错误要等流程真跑到那个节点才暴露。写完后务必发一条测试流程走一遍再上线。
挂到流程上:在 BPMN 设计器里挑
- 打开一个「流程类型 = BPMN 设计器」的模型,进入第三步「流程设计」;
- 选中用户任务节点,右侧属性面板里把「审批人」设为「流程表达式」;
- 点挑选按钮,弹出本页登记的表达式列表,选中一条即把表达式抄进该节点;
- 回模型页点「保 存」「发 布」。
编辑、状态与删除
- 行内「编辑」改名字 / 表达式;
- 状态列开关直接启用 / 禁用,提示「已开启」/「已关闭」;
- 行内「删除」确认后即删,后端不校验是否有流程正引用它。与监听器同理:已发布流程在发布时已把表达式抄进定义,删本页记录不影响存量流程,只影响以后新挂。
字段说明
| 字段 | 必填 | 取值 / 校验 | 说明 |
|---|---|---|---|
| 名字 | 是 | 「名字不能为空」 | 设计器挑选列表里显示的名字 |
| 状态 | 是 | 开启 / 关闭,默认开启 | — |
| 表达式 | 是 | 「表达式不能为空」;保存时不校验语法 | 求值结果必须是用户编号 |
视角对照
| 视角 | 看到什么 |
|---|---|
超管 admin / 租户管理员 docadmin | 全部表达式,可增删改 |
| 套餐未含此菜单的租户 | 侧边栏没有「流程表达式」 |
| 普通员工 | 无此菜单。表达式是开发向配置项 |
进阶
- 表达式 vs 用户分组:名单是固定的一批人时用 用户分组;名单要按流程数据现算(如「金额超 10 万找总监」「按表单里选的部门找负责人」)时用表达式;
- 表达式能读什么:流程变量、表单字段值、以及后端暴露的 Spring Bean。表单字段在发起时已写入流程变量,表达式里可直接引用字段标识;
- 预测类场景(流程还没跑到该节点时预览审批人)对含
execution的表达式会故意跳过——预览看不到人不代表配置错了,真跑到时才会算。
常见问题
Q:列表里那条名字「A」、表达式「1」的记录是什么? A:演示环境的测试残留。1 作为表达式会被求值成「用户编号 1」,即派单给 1 号用户——能跑,但毫无可读性,不要照抄这种写法。正式使用请写有语义的变量或 Bean 调用。
Q:保存时为什么不检查表达式对错? A:表达式要等派单时结合流程变量才能求值,保存时引擎没有上下文,所以只做非空校验。验证手段是发一条测试流程。
Q:简易设计器能用本页的表达式吗? A:不能直接挑。简易设计器审批人设置里的「流程表达式」是手写文本框,需要把表达式原文粘贴进去;本页登记的记录它不读。
Q:改了表达式,在途流程会变吗? A:不会。表达式在发布时抄进流程定义,改本页只影响之后新挂的节点;存量流程要重新挂并重新发布。
Q:表达式返回多个人会怎样? A:返回的集合里每个人都成为候选人,再按节点的「多人审批方式」(依次 / 会签 / 或签 / 随机一人)决定怎么批。
