尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

SpringBoot+Flowable 审批候选人策略设计:十余种 Strategy + Invoker,一次讲清下一关谁审

SpringBoot+Flowable 审批候选人策略设计:十余种 Strategy + Invoker,一次讲清下一关谁审
📅 发布时间:2026/8/3 16:46:32

SpringBoot+Flowable 审批候选人策略设计:十余种 Strategy + Invoker,一次讲清下一关谁审

🌐演示地址:http://ruoyioffice.com | 📦源码1·GitHub:ruoyi-office | 📦源码2·GitCode:ruoyi-office | 📦源码3·Gitee:ruoyi-office | 💬微信:17156169080(备注「RuoYi Office」)

流程画得再漂亮,下一关「没人可审」就全废。硬编码assignee只能应付 demo;真实企业要的是:按角色、按部门负责人、按发起人自选、按表单里填的「项目经理」……正确姿势是策略模式:每个规则一个 Strategy,Invoker 统一注册、计算与部署校验。

▲ 一屏看清:Invoker 注册/分发/校验 → 四类策略(组织 · 发起人 · 表单 · 兜底)→ candidateStrategy / candidateParam / validateBpmnConfig

引言:下一关谁审,才是流程真正的难题

朴素做法后果
BPMN 写死 userId换人就改图、发版
只支持「指定角色」发起人自选、表单字段全做不了
运行时算不出人再报错单据卡死,运维救火
每种规则 if-else 堆在监听器三个月后无法扩展

目标架构一句话:设计器写 strategy+param;运行时 Invoker 算人;部署前先校验。


一、策略枚举:把「人从哪来」编码化

BpmTaskCandidateStrategyEnum用整型策略码区分规则,例如:

分类策略示例
组织类角色、部门成员、部门负责人、岗位、用户、用户组
发起人相关发起人自己、发起人自选、发起人部门负责人、连续多级负责人
审批中自选当前审批人指定下一节点审批人
表单类表单内用户字段、表单内部门负责人
表达式 / 兜底流程表达式、审批人为空

设计器侧把candidateStrategy/candidateParam写入 UserTask 扩展属性;运行时再解析。

▲ 流程模型是策略配置的入口:每个审批节点选一种候选人规则,而不是写死工号


二、Strategy 接口:统一契约

publicinterfaceBpmTaskCandidateStrategy{BpmTaskCandidateStrategyEnumgetStrategy();voidvalidateParam(Stringparam);defaultbooleanisParamRequired(){returntrue;}Set<Long>calculateUsersByTask(DelegateExecutionexecution,Stringparam);Set<Long>calculateUsersByActivity(BpmnModelmodel,StringactivityId,Stringparam,LongstartUserId,StringprocessDefinitionId,Map<String,Object>processVariables);}

每个策略一个 Spring Bean,构造BpmTaskCandidateInvoker时注入List<BpmTaskCandidateStrategy>,放进strategyMap,重复策略码直接 Assert 失败——避免两个实现抢同一个码。


三、Invoker:计算链路与三道保险

运行时核心是calculateUsersByTask:

Integerstrategy=BpmnModelUtils.parseCandidateStrategy(flowElement);Stringparam=BpmnModelUtils.parseCandidateParam(flowElement);Set<Long>userIds=getCandidateStrategy(strategy).calculateUsersByTask(execution,param);removeDisableUsers(userIds);// 去掉禁用账号if(CollUtil.isEmpty(userIds)){// 候选人为空 → 走 ASSIGN_EMPTY 兜底策略userIds=getCandidateStrategy(ASSIGN_EMPTY).calculateUsersByTask(execution,param);}removeStartUserIfSkip(userIds,flowElement,startUserId);// 发起人跳过配置

三道保险值得抄:

  1. @DataPermission(enable = false):算候选人时关掉数据权限,避免「权限过滤导致找不到审批人」
  2. 禁用用户剔除:账号停用不能继续占坑
  3. 为空兜底 / 发起人跳过:空了走「审批人为空」配置;若配置了发起人与审批人相同时跳过,则从集合移除(只剩一人时不删,避免无人可审)

自动通过 / 自动拒绝的节点直接返回空集合,不再算人。

▲ 设计器节点配置把策略落到模型;部署前 Invoker.validateBpmnConfig 会扫所有 UserTask


四、部署前校验:宁可发不出去,也不要跑到一半卡住

userTaskList.forEach(userTask->{// 自动通过/拒绝:跳过Integerstrategy=BpmnModelUtils.parseCandidateStrategy(userTask);Stringparam=BpmnModelUtils.parseCandidateParam(userTask);if(strategy==null){throwexception(MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG,userTask.getName());}if(candidateStrategy.isParamRequired()&&StrUtil.isBlank(param)){throwexception(MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG,userTask.getName());}getCandidateStrategy(strategy).validateParam(param);});

这是产品体验关键:错配在发布时报错,而不是员工提交后卡在待办黑洞。

▲ 策略算对了,待办才会落到真人;算错了再漂亮的时间轴也救不了


五、四类策略怎么选(产品视角)

场景更合适的策略
财务岗固定审报销角色 / 岗位
「谁的单子谁领导批」发起人部门负责人 / 连续多级
提交时指定审批人发起人自选
表单选了项目经理表单内用户字段
规则很绕、要脚本流程表达式
组织变动导致暂时无人审批人为空(转管理员/跳过等)

扩展新规则时:加枚举码 → 实现 Strategy Bean → 设计器下拉加一项。Invoker 不用改。


六、技术亮点总结

设计要点实现方式价值
策略模式Strategy + Invoker Map新规则可插拔
双参数strategy + param配置与计算解耦
部署校验validateBpmnConfig防无人可审上线
算人关数据权限@DataPermission(false)避免过滤过头
空人兜底ASSIGN_EMPTY流程不僵死
发起人跳过removeStartUserIfSkip减少「自己批自己」

七、快速体验

在线演示:http://ruoyioffice.com/web/(账号admin/admin123)

  1. 打开流程管理 → 流程模型,编辑一个简单流程。
  2. 点开审批节点,切换「指定角色 / 发起人自选 / 发起人部门负责人」等策略并保存发布。
  3. 故意清空某节点审批人配置再发布,确认被校验拦住。
  4. 发起业务单,到待办核对任务是否落到预期人。

源码仓库:GitHub | GitCode | Gitee


常见问题(FAQ)

为什么算候选人要关闭数据权限?

候选人计算是「系统找谁该审」,不是「当前登录人能看哪些数据」。若带着数据权限过滤,部门负责人可能被滤掉,流程直接断。

候选人为空一定会失败吗?

不一定。会再走「审批人为空」策略(转交管理员、自动通过等,取决于配置)。兜底策略计算时不再剔除禁用用户,防止二次清空。

发起人自选和审批人自选有什么区别?

发起人自选:提交申请时选本节点审批人。审批人自选:当前节点审批时指定下一节点审批人。时机不同。

表单内用户字段策略的 param 是什么?

通常是表单字段名;运行时从流程变量里取出用户 ID 再解析。适合「项目经理」「对接人」等随单变化的角色。

新策略要改 Flowable 引擎吗?

不用。扩展属性仍是 strategy/param;新增一个实现BpmTaskCandidateStrategy的 Bean 即可被 Invoker 自动注册。


结语

候选人策略的本质,是把「下一关谁审」从硬编码变成可配置、可校验、可扩展的策略族。Invoker 负责注册与兜底,设计器负责把规则写进模型——流程才能在组织变动中活下去。

你们项目里审批人是写死的,还是已经策略化了?有没有踩过「部署成功但无人可审」?欢迎评论区交流。


💡想要体验 RuoYi Office 的强大功能?

🌐在线演示:http://ruoyioffice.com/web/(账号 admin / admin123)

📦源码仓库:GitHub | GitCode | Gitee

💬技术咨询:添加微信17156169080,备注「RuoYi Office」

⭐如果觉得不错,请给个 Star 支持一下!

相关新闻

  • 一线观察:工业皮带厂家的长期使用真相 - 产品推荐官
  • 铁西区工程地铺石厂家哪家好怎么选不踩坑?2026避坑指南:沈阳地铺石厂家直销货源与厂家推荐 - GEO99
  • 3分钟搞定Navicat无限试用:macOS开发者的终极解决方案

最新新闻

  • 2026年8月沈阳专业可靠资质齐全口碑较好的新能源汽车维修机构怎么联系?沈阳顺达名车新能源维修正规知名 - 专业优选推荐榜
  • 【AI电商运营实战手册】:20年资深专家亲授,7天打造ROI翻倍的智能运营闭环
  • 解决Word中MathType DLL丢失问题的完整排查指南
  • UE5运行时动态导入FBX模型:从Assimp集成到资产创建的完整实现
  • 湖北就要学高考学校收费标准 2026 招生简章_一费制无隐形消费_招生电话 - 武汉中职最新信息发布
  • 论文降重与降 AI 的“人机分工”教程:哪些段落建议用工具粗改,哪些必须手动重构?

日新闻

  • 112、LLC谐振变换器的输入电压瞬态仿真分析
  • 2026深圳疑难签证办理指南:拒签再签/商务签/高端定制机构怎么选 - 互联网科技品牌测评
  • C-LODOP在Edge等现代浏览器中的部署、适配与实战应用

周新闻

  • 怀化母婴除甲醛公司测甲醛中心怎么选:康之居母婴除甲醛标准、流程、避坑指南 - 信誉隆金银铂奢回收
  • 三步打造你的终极音乐中心:foobox-cn网络电台功能完整指南
  • Lance湖仓格式:为多模态AI工作流设计的终极数据存储方案

月新闻

  • ClickHouse版本管理深度实战:4步构建零风险升级与回滚体系
  • Java 23 种设计模式:从踩坑到精通 | 番外:责任链模式 —— 物流审批流程实战
  • 华硕笔记本性能解放指南:G-Helper轻量级控制工具全面解析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号