做流程平台开发的兄弟应该都有体会:流程引擎本身只是骨架,真正让流程“活”起来的,是挂在节点上那些动作(Action)。最近我在整理节点动作开发的资料,正好做到“添加带有选项选择的动作”这个需求——在某个节点上提供一个操作入口,点击之后不是直接执行,而是先弹出选项让操作人选择,再根据选择结果执行不同逻辑。这个功能在 OA、低代码平台、工单系统里都特别常见,做法也很有讲究。这篇文章我就把这个动作从设计、配置到前后端实现完整拆一遍,再把权限、安全级别、外部应用集成这些容易翻车的地方单独拎出来讲,希望能帮你少踩几个坑。
这套内容适合正在做流程节点二次开发的后端同学、需要设计操作交互的产品经理,以及被各种“动作不生效”报错折磨的运维和实施人员。不管你是用现成的流程引擎,还是自己写一套状态机,里面关于选项建模、参数传递、权限校验的思路都可以直接抄。
1. 先搞清楚:这个“动作”到底是个什么角色
1.1 流程节点里的动作是什么
在流程引擎里,节点(Node)是审批和业务流转的基本单位,而动作(Action)就是附着在节点上的可执行操作。你可以把节点理解成一扇门,动作就是门上挂的一排按钮:同意、退回、转办、加签、发起子流程……这些按钮背后各自对应一段执行逻辑。
动作和普通接口最大的区别在于它跟流程上下文强绑定。一个动作执行时,通常能拿到当前流程实例 ID、当前节点 ID、操作人、上一步的处理意见、表单数据等一堆上下文信息。这意味着你在写动作处理逻辑的时候,不需要自己去查“当前走到哪了”“是谁在操作”,引擎会把这些都塞给你。
不带选项选择的动作很简单,按钮一点就执行,中间没有任何交互。比如“同意”按钮,点了就直接走同意分支。但现实业务里,很多操作是需要操作人先做选择的。举个例子:审批不通过时,需要选择“驳回原因”——是“材料不齐”还是“内容有误”,不同原因要通知不同的人;又比如转办时需要选择把任务交给哪个具体的人或哪个角色。这时候,带选项选择的动作就派上用场了。
1.2 为什么非要带“选项选择”
有人会觉得,我多放几个按钮不就行了?比如“驳回-材料不齐”“驳回-内容有误”,一个原因一个按钮。这种做法在小规模场景下能凑合,但一旦选项变多就彻底失控了。你想想,如果驳回原因有 8 种,按钮栏会挤成一排;如果原因还会动态调整,每次改需求都要重新发布流程定义,这种方案根本没法维护。
选项选择的价值在于把“操作”和“参数”解耦。动作是同一个动作,但通过选项传入了不同的参数,动作逻辑根据参数做出不同响应。就像同一个“驳回”动作,配上不同的原因选项,既能做到统计口径统一,又不用为每个原因单独写一套逻辑。而且选项可以做成动态的,今天加一个原因,明天删一个原因,都不需要动流程定义和代码。
1.3 这类动作的典型应用场景
从我接触到的实际项目看,带选项选择的动作主要有这么几类典型场景:
一是分支决策型。操作人选择后,流程走向不同的下一个节点。比如财务审批里“通过但需补充说明”“通过但降低额度”这类选项,虽然都是通过,但后续处理路径不一样。
二是参数传递型。操作本身是固定的,但选项决定了执行细节。比如“转办”动作,选择“转给某人”还是“转给某角色”;“通知”动作,选择通知方式“站内信/邮件/短信”,同一个动作执行时走不同的发送通道。
三是批量处理型。在列表或归档节点上,对一批数据执行同一个操作,选项决定处理模式。比如“批量归档”时选择“按部门归档”还是“按项目归档”。
理解了动作的角色和选项选择的价值,接下来才能谈怎么设计。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 动作设计:把“选项选择”当成一个输入参数来建模
2.1 参数结构设计要点
很多开发第一次做带选项的动作时,下意识地在前端写死一个下拉框,然后调用后端接口。这种做法不是说完全不行,但对于流程平台这种需要配置化的场景,很容易做出一个“死”功能——换一个流程节点想用,得重新改代码。
正确的思路是把选项选择建模成动作的一个参数,而且这个参数要符合一定的结构。我在项目里常用的参数结构是这样的:
js复制
